Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype: unicode string support #1517

Draft
wants to merge 12 commits into
base: mc-1.19.x
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.core.terminal.VariableWidthTextBuffer;
import dan200.computercraft.shared.common.HeldItemMenu;
import dan200.computercraft.shared.media.items.PrintoutItem;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
Expand All @@ -27,7 +28,7 @@
public class PrintoutScreen extends AbstractContainerScreen<HeldItemMenu> {
private final boolean book;
private final int pages;
private final TextBuffer[] text;
private final VariableWidthTextBuffer[] text;
private final TextBuffer[] colours;
private int page;

Expand All @@ -37,8 +38,8 @@ public PrintoutScreen(HeldItemMenu container, Inventory player, Component title)
imageHeight = Y_SIZE;

var text = PrintoutItem.getText(container.getStack());
this.text = new TextBuffer[text.length];
for (var i = 0; i < this.text.length; i++) this.text[i] = new TextBuffer(text[i]);
this.text = new VariableWidthTextBuffer[text.length];
for (var i = 0; i < this.text.length; i++) this.text[i] = new VariableWidthTextBuffer(text[i]);

var colours = PrintoutItem.getColours(container.getStack());
this.colours = new TextBuffer[colours.length];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.util.StringUtil;
import dan200.computercraft.shared.computer.core.InputHandler;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -69,11 +70,30 @@ public TerminalWidget(Terminal terminal, InputHandler computer, int x, int y) {
innerHeight = terminal.getHeight() * FONT_HEIGHT;
}


private char lastSurrogate = 0;

@Override
public boolean charTyped(char ch, int modifiers) {
if (ch >= 32 && ch <= 126 || ch >= 160 && ch <= 255) {
if (ch >= 32 && ch <= 126 || ch >= 160) {
// Queue the char event for any printable chars in byte range
computer.queueEvent("char", new Object[]{ Character.toString(ch) });
if(lastSurrogate != 0){
var high = lastSurrogate;
lastSurrogate = 0;
if(Character.isSurrogatePair(high, ch)){
var s = Character.toString(Character.toCodePoint(high, ch));
computer.queueEvent("char", new Object[]{ s, StringUtil.utfToByteString(s) });
return true;
}
var s = Character.toString(high);
computer.queueEvent("char", new Object[]{ s, StringUtil.utfToByteString(s) });
}
if(Character.isHighSurrogate(ch)){
lastSurrogate = ch;
return true;
}
var s = Character.toString(ch);
computer.queueEvent("char", new Object[]{ s, StringUtil.utfToByteString(s) });
}

return true;
Expand Down Expand Up @@ -130,7 +150,7 @@ private void paste() {
if (!clipboard.isEmpty()) {
// Clip to 512 characters and queue the event
if (clipboard.length() > 512) clipboard = clipboard.substring(0, 512);
computer.queueEvent("paste", new Object[]{ clipboard });
computer.queueEvent("paste", new Object[]{ clipboard, StringUtil.utfToByteString(clipboard) });
}
}

Expand Down Expand Up @@ -162,6 +182,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
var charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
charX = Math.min(Math.max(charX, 0), terminal.getWidth() - 1);
charY = Math.min(Math.max(charY, 0), terminal.getHeight() - 1);
charX = terminal.getLine(charY).getIndexFromWidth(charX) + 1;

computer.mouseClick(button + 1, charX + 1, charY + 1);

Expand All @@ -181,6 +202,7 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) {
var charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
charX = Math.min(Math.max(charX, 0), terminal.getWidth() - 1);
charY = Math.min(Math.max(charY, 0), terminal.getHeight() - 1);
charX = terminal.getLine(charY).getIndexFromWidth(charX) + 1;

if (lastMouseButton == button) {
computer.mouseUp(lastMouseButton + 1, charX + 1, charY + 1);
Expand All @@ -202,6 +224,7 @@ public boolean mouseDragged(double mouseX, double mouseY, int button, double v2,
var charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
charX = Math.min(Math.max(charX, 0), terminal.getWidth() - 1);
charY = Math.min(Math.max(charY, 0), terminal.getHeight() - 1);
charX = terminal.getLine(charY).getIndexFromWidth(charX) + 1;

if (button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY)) {
computer.mouseDrag(button + 1, charX + 1, charY + 1);
Expand All @@ -221,6 +244,7 @@ public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
var charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
charX = Math.min(Math.max(charX, 0), terminal.getWidth() - 1);
charY = Math.min(Math.max(charY, 0), terminal.getHeight() - 1);
charX = terminal.getLine(charY).getIndexFromWidth(charX) + 1;

computer.mouseScroll(delta < 0 ? 1 : -1, charX + 1, charY + 1);

Expand Down Expand Up @@ -278,7 +302,7 @@ public void renderWidget(PoseStack transform, int mouseX, int mouseY, float part
if (!visible) return;

var bufferSource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL));
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL_FULLTEXT));

FixedWidthFontRenderer.drawTerminal(
emitter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected void renderItem(PoseStack transform, MultiBufferSource bufferSource, I
renderLight(transform, bufferSource, lightColour, width, height);

FixedWidthFontRenderer.drawTerminal(
FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL)),
FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL_FULLTEXT)),
MARGIN, MARGIN, terminal, MARGIN, MARGIN, MARGIN, MARGIN
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Palette;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.core.terminal.VariableWidthTextBuffer;
import net.minecraft.client.renderer.MultiBufferSource;
import org.joml.Matrix4f;

Expand Down Expand Up @@ -58,8 +59,8 @@ public final class PrintoutRenderer {
private PrintoutRenderer() {
}

public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours) {
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, VariableWidthTextBuffer[] text, TextBuffer[] colours) {
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_FULLTEXT);
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) {
FixedWidthFontRenderer.drawString(emitter,
Expand All @@ -70,12 +71,12 @@ public static void drawText(PoseStack transform, MultiBufferSource bufferSource,
}

public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, String[] text, String[] colours) {
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_FULLTEXT);
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) {
FixedWidthFontRenderer.drawString(emitter,
x, y + line * FONT_HEIGHT,
new TextBuffer(text[start + line]), new TextBuffer(colours[start + line]),
new VariableWidthTextBuffer(text[start + line]), new TextBuffer(colours[start + line]),
Palette.DEFAULT, light
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.mojang.blaze3d.vertex.VertexFormat;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.client.render.monitor.MonitorTextureBufferShader;
import dan200.computercraft.client.render.text.DynamicFontTexture;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.RenderStateShard;
Expand Down Expand Up @@ -35,6 +36,11 @@ public class RenderTypes {
*/
public static final RenderType TERMINAL = RenderType.text(FixedWidthFontRenderer.FONT);

/**
* Renders a fullbright terminal.
*/
public static final RenderType TERMINAL_FULLTEXT = RenderType.text(DynamicFontTexture.DEFAULT_NAME);

/**
* Renders a monitor with the TBO shader.
*
Expand All @@ -47,6 +53,11 @@ public class RenderTypes {
*/
public static final RenderType PRINTOUT_TEXT = RenderType.text(FixedWidthFontRenderer.FONT);

/**
* A variant of {@link #TERMINAL} which uses the lightmap rather than rendering fullbright.
*/
public static final RenderType PRINTOUT_FULLTEXT = RenderType.text(DynamicFontTexture.DEFAULT_NAME);

/**
* Printout's background texture. {@link RenderType#text(ResourceLocation)} is a <em>little</em> questionable, but
* it is what maps use, so should behave the same as vanilla in both item frames and in-hand.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.client.render.text.TerminalFont;
import dan200.computercraft.client.render.vbo.DirectBuffers;
import dan200.computercraft.client.render.vbo.DirectVertexBuffer;
import dan200.computercraft.core.terminal.Terminal;
Expand Down Expand Up @@ -124,7 +125,7 @@ public void render(MonitorBlockEntity monitor, float partialTicks, PoseStack tra
transform.popPose();
} else {
FixedWidthFontRenderer.drawEmptyTerminal(
FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL)),
FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL_FULLTEXT)),
-MARGIN, MARGIN,
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
);
Expand All @@ -140,7 +141,8 @@ private static void renderTerminal(
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;

var renderType = currentRenderer();
var redraw = monitor.pollTerminalChanged();
var redraw = monitor.pollTerminalChanged()
|| renderState.lastFontTextureSize != TerminalFont.getInstance().getTextureSize(); // need to recalculate uv coordinate
if (renderState.createBuffer(renderType)) redraw = true;

switch (renderType) {
Expand Down Expand Up @@ -176,6 +178,9 @@ private static void renderTerminal(
var backgroundBuffer = assertNonNull(renderState.backgroundBuffer);
var foregroundBuffer = assertNonNull(renderState.foregroundBuffer);
if (redraw) {
for (int i = 0; i < terminal.getHeight(); i++) {
TerminalFont.getInstance().preloadCharacterFont(terminal.getLine(i));
}
var size = DirectFixedWidthFontRenderer.getVertexCount(terminal);

// In an ideal world we could upload these both into one buffer. However, we can't render VBOs with
Expand All @@ -198,7 +203,7 @@ private static void renderTerminal(
var oldInverseRotation = RenderSystem.getInverseViewRotationMatrix();
RenderSystem.setInverseViewRotationMatrix(IDENTITY_NORMAL);

RenderTypes.TERMINAL.setupRenderState();
RenderTypes.TERMINAL_FULLTEXT.setupRenderState();

// Render background geometry
backgroundBuffer.bind();
Expand All @@ -220,13 +225,14 @@ private static void renderTerminal(
// Clear state
RenderSystem.polygonOffset(0.0f, -0.0f);
RenderSystem.disablePolygonOffset();
RenderTypes.TERMINAL.clearRenderState();
RenderTypes.TERMINAL_FULLTEXT.clearRenderState();
VertexBuffer.unbind();

RenderSystem.setInverseViewRotationMatrix(oldInverseRotation);
}
case BEST -> throw new IllegalStateException("Impossible: Should never use BEST renderer");
}
renderState.lastFontTextureSize = TerminalFont.getInstance().getTextureSize();
}

private static void renderToBuffer(DirectVertexBuffer vbo, int size, Consumer<DirectFixedWidthFontRenderer.QuadEmitter> draw) {
Expand All @@ -235,7 +241,7 @@ private static void renderToBuffer(DirectVertexBuffer vbo, int size, Consumer<Di

draw.accept(sink);
buffer.flip();
vbo.upload(buffer.limit() / sink.format().getVertexSize(), RenderTypes.TERMINAL.mode(), sink.format(), buffer);
vbo.upload(buffer.limit() / sink.format().getVertexSize(), RenderTypes.TERMINAL_FULLTEXT.mode(), sink.format(), buffer);
}

private static void tboVertex(VertexConsumer builder, Matrix4f matrix, float x, float y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class MonitorRenderState implements ClientMonitor.RenderState {
private static final Set<MonitorRenderState> allMonitors = new HashSet<>();

public long lastRenderFrame = -1;
public int lastFontTextureSize = -1;
public @Nullable BlockPos lastRenderPos = null;

public int tboBuffer;
Expand Down
Loading