1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-09-06 04:17:56 +00:00

printout renderer, terminal, tile printer, fake player, guicomputer, fixed width font renderer

This commit is contained in:
Devan-Kerman
2020-08-29 18:47:47 -05:00
parent a4830aff86
commit 2ea816b78b
6 changed files with 421 additions and 248 deletions

View File

@@ -19,7 +19,7 @@ import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.block.entity.CommandBlockBlockEntity;
import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.command.arguments.EntityAnchorArgumentType; import net.minecraft.command.argument.EntityAnchorArgumentType;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectInstance;
@@ -139,7 +139,7 @@ public class FakePlayer extends ServerPlayerEntity {
protected void consumeItem() { } protected void consumeItem() { }
@Override @Override
public void lookAt(EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d) { } public void lookAt(EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d) {}
@Override @Override
public void method_14222(EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target) { } public void method_14222(EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target) { }

View File

@@ -9,191 +9,320 @@ package dan200.computercraft.client.gui;
import java.util.Arrays; import java.util.Arrays;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.texture.TextureManager; import net.minecraft.client.texture.TextureManager;
import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Matrix4f;
@SuppressWarnings ({
"MethodCallSideOnly",
"LocalVariableDeclarationSideOnly",
"VariableUseSideOnly"
})
public final class FixedWidthFontRenderer { public final class FixedWidthFontRenderer {
public static final Identifier BACKGROUND = new Identifier("computercraft", "textures/gui/term_background.png"); private static final Matrix4f IDENTITY = AffineTransformation.identity().getMatrix();
private static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
public static final int FONT_HEIGHT = 9; public static final int FONT_HEIGHT = 9;
public static final int FONT_WIDTH = 6; public static final int FONT_WIDTH = 6;
private static final Identifier FONT = new Identifier("computercraft", "textures/gui/term_font.png"); public static final float WIDTH = 256.0f;
private static FixedWidthFontRenderer instance;
private final TextureManager m_textureManager;
private FixedWidthFontRenderer() { public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH;
this.m_textureManager = MinecraftClient.getInstance() public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH;
.getTextureManager();
public static final RenderLayer TYPE = Type.MAIN;
private FixedWidthFontRenderer()
{
} }
public static FixedWidthFontRenderer instance() { public static float toGreyscale( double[] rgb )
if (instance != null) { {
return instance; return (float) ((rgb[0] + rgb[1] + rgb[2]) / 3);
}
return instance = new FixedWidthFontRenderer();
} }
public void drawString(TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, public static int getColour( char c, Colour def )
boolean greyScale, Palette p) { {
// Draw background return 15 - Terminal.getColour(c, def );
if (backgroundColour != null) {
// Bind the background texture
this.m_textureManager.bindTextureInner(BACKGROUND);
// Draw the quads
this.drawStringBackgroundPart(x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p);
}
// Draw text
if (s != null && textColour != null) {
// Bind the font texture
this.bindFont();
// Draw the quads
this.drawStringTextPart(x, y, s, textColour, greyScale, p);
}
} }
public void drawStringBackgroundPart(int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, private static void drawQuad(Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b )
Palette p) { {
// Draw the quads buffer.vertex( transform, x, y, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_START, BACKGROUND_START ).next();
Tessellator tessellator = Tessellator.getInstance(); buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_START, BACKGROUND_END ).next();
BufferBuilder renderer = tessellator.getBuffer(); buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_END, BACKGROUND_START ).next();
renderer.begin(GL11.GL_TRIANGLES, VertexFormats.POSITION_COLOR); buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_END, BACKGROUND_START ).next();
if (leftMarginSize > 0.0) { buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_START, BACKGROUND_END ).next();
int colour1 = "0123456789abcdef".indexOf(backgroundColour.charAt(0)); buffer.vertex( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).texture( BACKGROUND_END, BACKGROUND_END ).next();
if (colour1 < 0 || (greyScale && !this.isGreyScale(colour1))) { }
colour1 = 15;
private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex )
{
double[] colour = palette.getColour( getColour( colourIndex, Colour.Black ) );
float r, g, b;
if( greyscale )
{
r = g = b = toGreyscale( colour );
}
else
{
r = (float) colour[0];
g = (float) colour[1];
b = (float) colour[2];
}
drawQuad( transform, buffer, x, y, width, height, r, g, b );
}
private static void drawBackground(
Matrix4f transform, VertexConsumer renderer, float x, float y,
TextBuffer backgroundColour, Palette palette, boolean greyscale,
float leftMarginSize, float rightMarginSize, float height
)
{
if( leftMarginSize > 0 )
{
drawQuad( transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt( 0 ) );
}
if( rightMarginSize > 0 )
{
drawQuad( transform, renderer, x + backgroundColour.length() * FONT_WIDTH, y, rightMarginSize, height, palette, greyscale, backgroundColour.charAt( backgroundColour.length() - 1 ) );
}
// Batch together runs of identical background cells.
int blockStart = 0;
char blockColour = '\0';
for( int i = 0; i < backgroundColour.length(); i++ )
{
char colourIndex = backgroundColour.charAt( i );
if( colourIndex == blockColour ) continue;
if( blockColour != '\0' )
{
drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour );
} }
this.drawQuad(renderer, x - leftMarginSize, y, colour1, leftMarginSize, p, greyScale);
blockColour = colourIndex;
blockStart = i;
} }
if (rightMarginSize > 0.0) {
int colour2 = "0123456789abcdef".indexOf(backgroundColour.charAt(backgroundColour.length() - 1)); if( blockColour != '\0' )
if (colour2 < 0 || (greyScale && !this.isGreyScale(colour2))) { {
colour2 = 15; drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (backgroundColour.length() - blockStart), height, palette, greyscale, blockColour );
}
this.drawQuad(renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize, p, greyScale);
} }
for (int i = 0; i < backgroundColour.length(); i++) {
int colour = "0123456789abcdef".indexOf(backgroundColour.charAt(i));
if (colour < 0 || (greyScale && !this.isGreyScale(colour))) {
colour = 15;
}
this.drawQuad(renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale);
}
GlStateManager.disableTexture();
tessellator.draw();
GlStateManager.enableTexture();
} }
public void bindFont() { public static void drawString(
this.m_textureManager.bindTextureInner(FONT); Matrix4f transform, VertexConsumer renderer, float x, float y,
GlStateManager.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP); TextBuffer text, TextBuffer textColour, TextBuffer backgroundColour,
} Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize
)
{
if( backgroundColour != null )
{
drawBackground( transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT );
}
public void drawStringTextPart(int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p) { for( int i = 0; i < text.length(); i++ )
// Draw the quads {
Tessellator tessellator = Tessellator.getInstance(); double[] colour = palette.getColour( getColour( textColour.charAt( i ), Colour.Black ) );
BufferBuilder renderer = tessellator.getBuffer(); float r, g, b;
renderer.begin(GL11.GL_TRIANGLES, VertexFormats.POSITION_TEXTURE_COLOR); if( greyscale )
for (int i = 0; i < s.length(); i++) { {
// Switch colour r = g = b = toGreyscale( colour );
int colour = "0123456789abcdef".indexOf(textColour.charAt(i)); }
if (colour < 0 || (greyScale && !this.isGreyScale(colour))) { else
colour = 0; {
r = (float) colour[0];
g = (float) colour[1];
b = (float) colour[2];
} }
// Draw char // Draw char
int index = s.charAt(i); int index = text.charAt( i );
if (index < 0 || index > 255) { if( index > 255 ) index = '?';
index = '?'; drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b );
}
}
public static void drawString(
float x, float y, TextBuffer text, TextBuffer textColour, TextBuffer backgroundColour,
Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize
)
{
bindFont();
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
drawString( IDENTITY, ((VertexConsumerProvider) renderer).getBuffer( TYPE ), x, y, text, textColour, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize );
renderer.draw();
}
public static void drawTerminalWithoutCursor(
Matrix4f transform, VertexConsumer buffer, float x, float y,
Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
Palette palette = terminal.getPalette();
int height = terminal.getHeight();
// Top and bottom margins
drawBackground(
transform, buffer, x, y - topMarginSize,
terminal.getBackgroundColourLine( 0 ), palette, greyscale,
leftMarginSize, rightMarginSize, topMarginSize
);
drawBackground(
transform, buffer, x, y + height * FONT_HEIGHT,
terminal.getBackgroundColourLine( height - 1 ), palette, greyscale,
leftMarginSize, rightMarginSize, bottomMarginSize
);
// The main text
for( int i = 0; i < height; i++ )
{
drawString(
transform, buffer, x, y + FixedWidthFontRenderer.FONT_HEIGHT * i,
terminal.getLine( i ), terminal.getTextColourLine( i ), terminal.getBackgroundColourLine( i ),
palette, greyscale, leftMarginSize, rightMarginSize
);
}
}
public static void drawCursor(
Matrix4f transform, VertexConsumer buffer, float x, float y,
Terminal terminal, boolean greyscale
)
{
Palette palette = terminal.getPalette();
int width = terminal.getWidth();
int height = terminal.getHeight();
int cursorX = terminal.getCursorX();
int cursorY = terminal.getCursorY();
if(terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height && FrameInfo.getGlobalCursorBlink() )
{
double[] colour = palette.getColour( 15 - terminal.getTextColour() );
float r, g, b;
if( greyscale )
{
r = g = b = toGreyscale( colour );
} }
this.drawChar(renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale); else
{
r = (float) colour[0];
g = (float) colour[1];
b = (float) colour[2];
}
drawChar( transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b );
} }
tessellator.draw();
} }
private boolean isGreyScale(int colour) { public static void drawTerminal(
return colour == 0 || colour == 15 || colour == 7 || colour == 8; Matrix4f transform, VertexConsumer buffer, float x, float y,
Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
drawTerminalWithoutCursor( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
drawCursor( transform, buffer, x, y, terminal, greyscale );
} }
private void drawQuad(BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale) { public static void drawTerminal(
double[] colour = p.getColour(15 - color); Matrix4f transform, float x, float y, Terminal terminal, boolean greyscale,
if (greyscale) { float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
greyscaleify(colour); )
} {
float r = (float) colour[0]; bindFont();
float g = (float) colour[1];
float b = (float) colour[2];
renderer.vertex(x, y, 0.0) VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
.color(r, g, b, 1.0f) VertexConsumer buffer = renderer.getBuffer( TYPE );
.next(); drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
renderer.vertex(x, y + FONT_HEIGHT, 0.0) renderer.draw( TYPE );
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + width, y, 0.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + width, y, 0.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x, y + FONT_HEIGHT, 0.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + width, y + FONT_HEIGHT, 0.0)
.color(r, g, b, 1.0f)
.next();
} }
private void drawChar(BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale) { public static void drawTerminal(
float x, float y, Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
drawTerminal( IDENTITY, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
}
public static void drawEmptyTerminal( Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float width, float height )
{
Colour colour = Colour.Black;
drawQuad( transform, renderer.getBuffer( TYPE ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
}
public static void drawEmptyTerminal( Matrix4f transform, float x, float y, float width, float height )
{
bindFont();
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers();
drawEmptyTerminal( transform, renderer, x, y, width, height );
renderer.draw();
}
public static void drawEmptyTerminal( float x, float y, float width, float height )
{
drawEmptyTerminal( IDENTITY, x, y, width, height );
}
public static void drawBlocker( Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float width, float height )
{
Colour colour = Colour.Black;
drawQuad( transform, renderer.getBuffer( Type.BLOCKER ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
}
private static void bindFont()
{
MinecraftClient.getInstance().getTextureManager().bindTexture( FONT );
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
}
private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b )
{
// Short circuit to avoid the common case - the texture should be blank here after all.
if( index == '\0' || index == ' ' ) return;
int column = index % 16; int column = index % 16;
int row = index / 16; int row = index / 16;
double[] colour = p.getColour(15 - color);
if (greyscale) {
greyscaleify(colour);
}
float r = (float) colour[0];
float g = (float) colour[1];
float b = (float) colour[2];
int xStart = 1 + column * (FONT_WIDTH + 2); int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2); int yStart = 1 + row * (FONT_HEIGHT + 2);
renderer.vertex(x, y, 0.0) buffer.vertex( transform, x, y, 0f ).color( r, g, b, 1.0f ).texture( xStart / WIDTH, yStart / WIDTH ).next();
.texture(xStart / 256.0, yStart / 256.0) buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).next();
.next(); buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).next();
renderer.vertex(x, y + FONT_HEIGHT, 0.0) buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).next();
.texture(xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0) buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).texture( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).next();
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + FONT_WIDTH, y, 0.0)
.texture((xStart + FONT_WIDTH) / 256.0, yStart / 256.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + FONT_WIDTH, y, 0.0)
.texture((xStart + FONT_WIDTH) / 256.0, yStart / 256.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x, y + FONT_HEIGHT, 0.0)
.texture(xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0)
.color(r, g, b, 1.0f)
.next();
renderer.vertex(x + FONT_WIDTH, y + FONT_HEIGHT, 0.0)
.texture((xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0)
.color(r, g, b, 1.0f)
.next();
} }
private static void greyscaleify(double[] rgb) { private static void greyscaleify(double[] rgb) {
Arrays.fill(rgb, (rgb[0] + rgb[1] + rgb[2]) / 3.0f); Arrays.fill(rgb, (rgb[0] + rgb[1] + rgb[2]) / 3.0f);
} }
@@ -204,4 +333,39 @@ public final class FixedWidthFontRenderer {
} }
return s.length() * FONT_WIDTH; return s.length() * FONT_WIDTH;
} }
private static final class Type extends RenderPhase
{
private static final int GL_MODE = GL11.GL_TRIANGLES;
private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE;
static final RenderLayer MAIN = RenderLayer.of(
"terminal_font", FORMAT, GL_MODE, 1024,
false, false, // useDelegate, needsSorting
RenderLayer.MultiPhaseParameters.builder()
.texture( new Texture(FONT, false, false ) ) // blur, minimap
.alpha( ONE_TENTH_ALPHA )
.lightmap( DISABLE_LIGHTMAP )
.writeMaskState( COLOR_MASK )
.build( false )
);
static final RenderLayer BLOCKER = RenderLayer.of(
"terminal_blocker", FORMAT, GL_MODE, 256,
false, false, // useDelegate, needsSorting
RenderLayer.MultiPhaseParameters.builder()
.texture( new Texture(FONT, false, false ) ) // blur, minimap
.alpha( ONE_TENTH_ALPHA )
.writeMaskState( DEPTH_MASK )
.lightmap( DISABLE_LIGHTMAP )
.build( false )
);
private Type( String name, Runnable setup, Runnable destroy )
{
super( name, setup, destroy );
}
}
} }

View File

@@ -25,6 +25,7 @@ import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> { public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> {
private static final MinecraftClient MINECRAFT = MinecraftClient.getInstance();
public static final Identifier BACKGROUND_NORMAL = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_normal.png"); public static final Identifier BACKGROUND_NORMAL = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_normal.png");
public static final Identifier BACKGROUND_ADVANCED = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png"); public static final Identifier BACKGROUND_ADVANCED = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png");
public static final Identifier BACKGROUND_COMMAND = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_command.png"); public static final Identifier BACKGROUND_COMMAND = new Identifier(ComputerCraft.MOD_ID, "textures/gui/corners_command.png");
@@ -60,7 +61,7 @@ public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> {
@Override @Override
protected void init() { protected void init() {
MinecraftClient.getInstance().keyboard.enableRepeatEvents(true); MinecraftClient.getInstance().keyboard.setRepeatEvents(true);
int termPxWidth = this.m_termWidth * FixedWidthFontRenderer.FONT_WIDTH; int termPxWidth = this.m_termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = this.m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT; int termPxHeight = this.m_termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
@@ -70,7 +71,7 @@ public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> {
super.init(); super.init();
this.terminal = new WidgetTerminal(minecraft, () -> this.m_computer, this.m_termWidth, this.m_termHeight, 2, 2, 2, 2); this.terminal = new WidgetTerminal(MINECRAFT, () -> this.m_computer, this.m_termWidth, this.m_termHeight, 2, 2, 2, 2);
this.terminalWrapper = new WidgetWrapper(this.terminal, 2 + 12 + this.x, 2 + 12 + this.y, termPxWidth, termPxHeight); this.terminalWrapper = new WidgetWrapper(this.terminal, 2 + 12 + this.x, 2 + 12 + this.y, termPxWidth, termPxHeight);
this.children.add(this.terminalWrapper); this.children.add(this.terminalWrapper);
@@ -100,16 +101,16 @@ public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> {
switch (this.m_family) { switch (this.m_family) {
case Normal: case Normal:
default: default:
minecraft.getTextureManager() MINECRAFT.getTextureManager()
.bindTextureInner(BACKGROUND_NORMAL); .bindTexture(BACKGROUND_NORMAL);
break; break;
case Advanced: case Advanced:
minecraft.getTextureManager() MINECRAFT.getTextureManager()
.bindTextureInner(BACKGROUND_ADVANCED); .bindTexture(BACKGROUND_ADVANCED);
break; break;
case Command: case Command:
minecraft.getTextureManager() MINECRAFT.getTextureManager()
.bindTextureInner(BACKGROUND_COMMAND); .bindTexture(BACKGROUND_COMMAND);
break; break;
} }
@@ -152,7 +153,7 @@ public class GuiComputer<T extends ScreenHandler> extends HandledScreen<T> {
super.removed(); super.removed();
this.children.remove(this.terminal); this.children.remove(this.terminal);
this.terminal = null; this.terminal = null;
minecraft.keyboard.enableRepeatEvents(false); MINECRAFT.keyboard.setRepeatEvents(false);
} }
@Override @Override

View File

@@ -9,20 +9,23 @@ package dan200.computercraft.client.render;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.client.gui.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Matrix4f;
@SuppressWarnings ({
"LocalVariableDeclarationSideOnly",
"MethodCallSideOnly"
})
public final class PrintoutRenderer { public final class PrintoutRenderer {
/** /**
* Width of a page * Width of a page
@@ -45,7 +48,7 @@ public final class PrintoutRenderer {
*/ */
public static final int COVER_SIZE = 12; public static final int COVER_SIZE = 12;
private static final Identifier BG = new Identifier("computercraft", "textures/gui/printout.png"); private static final Identifier BG = new Identifier("computercraft", "textures/gui/printout.png");
private static final double BG_SIZE = 256.0; private static final float BG_SIZE = 256.0f;
/** /**
* Width of the extra page texture * Width of the extra page texture
*/ */
@@ -55,125 +58,120 @@ public final class PrintoutRenderer {
private PrintoutRenderer() {} private PrintoutRenderer() {}
public static void drawText(int x, int y, int start, TextBuffer[] text, TextBuffer[] colours) { public static void drawText(Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours) {
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance(); VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE );
for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
for (int line = 0; line < LINES_PER_PAGE && line < text.length; line++) { {
fontRenderer.drawString(text[start + line], x, y + line * FONT_HEIGHT, colours[start + line], null, 0, 0, false, Palette.DEFAULT); FixedWidthFontRenderer.drawString( transform, buffer,
x, y + line * FONT_HEIGHT, text[start + line], colours[start + line], null, Palette.DEFAULT,
false, 0, 0
);
} }
} }
public static void drawText(int x, int y, int start, String[] text, String[] colours) { public static void drawText(Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, String[] text, String[] colours) {
GlStateManager.color4f(1.0f, 1.0f, 1.0f, 1.0f); VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE );
GlStateManager.enableBlend(); for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
GlStateManager.enableTexture(); {
GlStateManager.blendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO); FixedWidthFontRenderer.drawString( transform, buffer,
x, y + line * FONT_HEIGHT,
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance(); new TextBuffer( text[start + line] ), new TextBuffer( colours[start + line] ),
null, Palette.DEFAULT, false, 0, 0
for (int line = 0; line < LINES_PER_PAGE && line < text.length; line++) { );
fontRenderer.drawString(new TextBuffer(text[start + line]),
x,
y + line * FONT_HEIGHT,
new TextBuffer(colours[start + line]),
null,
0,
0,
false,
Palette.DEFAULT);
} }
} }
public static void drawBorder(double x, double y, double z, int page, int pages, boolean isBook) { @SuppressWarnings ("MethodCallSideOnly")
GlStateManager.color4f(1.0f, 1.0f, 1.0f, 1.0f); public static void drawBorder(Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float z, int page, int pages, boolean isBook) {
GlStateManager.enableBlend();
GlStateManager.enableTexture();
GlStateManager.blendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO);
MinecraftClient.getInstance()
.getTextureManager()
.bindTextureInner(BG);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_TEXTURE);
int leftPages = page; int leftPages = page;
int rightPages = pages - page - 1; int rightPages = pages - page - 1;
if (isBook) { VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE );
if( isBook )
{
// Border // Border
double offset = offsetAt(pages); float offset = offsetAt( pages );
final double left = x - 4 - offset; float left = x - 4 - offset;
final double right = x + X_SIZE + offset - 4; float right = x + X_SIZE + offset - 4;
// Left and right border // Left and right border
drawTexture(buffer, left - 4, y - 8, z - 0.02, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2); drawTexture( transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 );
drawTexture(buffer, right, y - 8, z - 0.02, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2); drawTexture( transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 );
// Draw centre panel (just stretched texture, sorry). // Draw centre panel (just stretched texture, sorry).
drawTexture(buffer, x - offset, y, z - 0.02, X_SIZE + offset * 2, Y_SIZE, COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE); drawTexture( transform, buffer,
x - offset, y, z - 0.02f, X_SIZE + offset * 2, Y_SIZE,
COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE
);
double borderX = left; float borderX = left;
while (borderX < right) { while( borderX < right )
double thisWidth = Math.min(right - borderX, X_SIZE); {
drawTexture(buffer, borderX, y - 8, z - 0.02, 0, COVER_Y, thisWidth, COVER_SIZE); double thisWidth = Math.min( right - borderX, X_SIZE );
drawTexture(buffer, borderX, y + Y_SIZE - 4, z - 0.02, 0, COVER_Y + COVER_SIZE, thisWidth, COVER_SIZE); drawTexture( transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE );
drawTexture( transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE );
borderX += thisWidth; borderX += thisWidth;
} }
} }
// Left half // Left half
drawTexture(buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE); drawTexture( transform, buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE );
for (int n = 0; n <= leftPages; n++) { for( int n = 0; n <= leftPages; n++ )
drawTexture(buffer, x - offsetAt(n), y, z - 1e-3 * n, {
// Use the left "bold" fold for the outermost page drawTexture( transform, buffer,
n == leftPages ? 0 : X_FOLD_SIZE, 0, X_FOLD_SIZE, Y_SIZE); x - offsetAt( n ), y, z - 1e-3f * n,
// Use the left "bold" fold for the outermost page
n == leftPages ? 0 : X_FOLD_SIZE, 0,
X_FOLD_SIZE, Y_SIZE
);
} }
// Right half // Right half
drawTexture(buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE); drawTexture( transform, buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE );
for (int n = 0; n <= rightPages; n++) { for( int n = 0; n <= rightPages; n++ )
drawTexture(buffer, x + (X_SIZE - X_FOLD_SIZE) + offsetAt(n), y, z - 1e-3 * n, {
// Two folds, then the main page. Use the right "bold" fold for the outermost page. drawTexture( transform, buffer,
X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0, X_FOLD_SIZE, Y_SIZE); x + (X_SIZE - X_FOLD_SIZE) + offsetAt( n ), y, z - 1e-3f * n,
// Two folds, then the main page. Use the right "bold" fold for the outermost page.
X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0,
X_FOLD_SIZE, Y_SIZE
);
} }
tessellator.draw();
} }
public static double offsetAt(int page) { private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height )
return 32 * (1 - Math.pow(1.2, -page)); {
buffer.vertex( matrix, x, y + height, z ).texture( u / BG_SIZE, (v + height) / BG_SIZE ).next();
buffer.vertex( matrix, x + width, y + height, z ).texture( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).next();
buffer.vertex( matrix, x + width, y, z ).texture( (u + width) / BG_SIZE, v / BG_SIZE ).next();
buffer.vertex( matrix, x, y, z ).texture( u / BG_SIZE, v / BG_SIZE ).next();
} }
private static void drawTexture(BufferBuilder buffer, double x, double y, double z, double u, double v, double width, double height) { private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight )
buffer.vertex(x, y + height, z) {
.texture(u / BG_SIZE, (v + height) / BG_SIZE) buffer.vertex( matrix, x, y + height, z ).texture( u / BG_SIZE, (v + tHeight) / BG_SIZE ).next();
.next(); buffer.vertex( matrix, x + width, y + height, z ).texture( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).next();
buffer.vertex(x + width, y + height, z) buffer.vertex( matrix, x + width, y, z ).texture( (u + tWidth) / BG_SIZE, v / BG_SIZE ).next();
.texture((u + width) / BG_SIZE, (v + height) / BG_SIZE) buffer.vertex( matrix, x, y, z ).texture( u / BG_SIZE, v / BG_SIZE ).next();
.next();
buffer.vertex(x + width, y, z)
.texture((u + width) / BG_SIZE, v / BG_SIZE)
.next();
buffer.vertex(x, y, z)
.texture(u / BG_SIZE, v / BG_SIZE)
.next();
} }
private static void drawTexture(BufferBuilder buffer, double x, double y, double z, double width, double height, double u, double v, double tWidth, public static float offsetAt( int page )
double tHeight) { {
buffer.vertex(x, y + height, z) return (float) (32 * (1 - Math.pow( 1.2, -page )));
.texture(u / BG_SIZE, (v + tHeight) / BG_SIZE) }
.next();
buffer.vertex(x + width, y + height, z) private static final class Type extends RenderPhase {
.texture((u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE) static final RenderLayer TYPE = RenderLayer.of("printout_background", VertexFormats.POSITION_COLOR_TEXTURE, GL11.GL_QUADS, 1024, false, false,
.next(); // useDelegate, needsSorting
buffer.vertex(x + width, y, z) RenderLayer.MultiPhaseParameters.builder()
.texture((u + tWidth) / BG_SIZE, v / BG_SIZE) .texture(new RenderLayer.Texture(BG, false, false)) // blur, minimap
.next(); .alpha(ONE_TENTH_ALPHA)
buffer.vertex(x, y, z) .lightmap(DISABLE_LIGHTMAP)
.texture(u / BG_SIZE, v / BG_SIZE) .build(false));
.next();
private Type(String name, Runnable setup, Runnable destroy) {
super(name, setup, destroy);
}
} }
} }

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.core.terminal; package dan200.computercraft.core.terminal;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@@ -321,4 +322,11 @@ public class Terminal {
} }
this.setChanged(); this.setChanged();
} }
public static int getColour( char c, Colour def )
{
if( c >= '0' && c <= '9' ) return c - '0';
if( c >= 'a' && c <= 'f' ) return c - 'a' + 10;
return 15 - def.ordinal();
}
} }

View File

@@ -173,8 +173,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
} }
@Override @Override
public void fromTag(CompoundTag nbt) { public void fromTag(BlockState state, CompoundTag nbt) {
super.fromTag(nbt); super.fromTag(state, nbt);
this.customName = nbt.contains(NBT_NAME) ? LiteralText.Serializer.fromJson(nbt.getString(NBT_NAME)) : null; this.customName = nbt.contains(NBT_NAME) ? LiteralText.Serializer.fromJson(nbt.getString(NBT_NAME)) : null;
@@ -492,6 +492,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
@Nonnull @Nonnull
@Override @Override
public Text getName() { public Text getName() {
// todo possible crash problem
//noinspection MethodCallSideOnly
return this.customName != null ? this.customName : this.getCachedState().getBlock() return this.customName != null ? this.customName : this.getCachedState().getBlock()
.getName(); .getName();
} }