More monitor fixes, new monitor model

This commit is contained in:
Jackson Abney
2024-05-27 04:25:19 -08:00
parent a8cbd46d9d
commit deabaf56e8
22 changed files with 1400 additions and 127 deletions

View File

@@ -6,21 +6,18 @@ import com.mojang.blaze3d.platform.InputConstants;
import li.cil.oc2.client.gui.widget.ImageButton;
import li.cil.oc2.client.gui.widget.ToggleImageButton;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.container.AbstractMachineTerminalContainer;
import li.cil.oc2.common.container.AbstractMonitorContainer;
import li.cil.oc2.common.util.TooltipUtils;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.world.entity.player.Inventory;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.ArrayList;
import java.util.List;
import static java.util.Arrays.asList;
@@ -46,27 +43,6 @@ public abstract class AbstractMonitorDisplayScreen<T extends AbstractMonitorCont
///////////////////////////////////////////////////////////////////
public static boolean isInputCaptureEnabled() {
return isInputCaptureEnabled;
}
public List<Rect2i> getExtraAreas() {
final List<Rect2i> list = new ArrayList<>();
list.add(new Rect2i(
leftPos - Sprites.SIDEBAR_3.width, topPos + CONTROLS_TOP,
Sprites.SIDEBAR_3.width, Sprites.SIDEBAR_3.height
));
if (shouldRenderEnergyBar()) {
list.add(new Rect2i(
leftPos - Sprites.SIDEBAR_2.width, topPos + ENERGY_TOP,
Sprites.SIDEBAR_2.width, Sprites.SIDEBAR_2.height
));
}
return list;
}
@Override
public void containerTick() {
super.containerTick();
@@ -213,7 +189,7 @@ public abstract class AbstractMonitorDisplayScreen<T extends AbstractMonitorCont
Sprites.ENERGY_BAR.drawFillY(graphics, x, y, menu.getEnergy() / (float) menu.getEnergyCapacity());
}
terminalWidget.render(graphics, mouseX, mouseY, Component.literal("RENDERING"));
terminalWidget.render(graphics, mouseX, mouseY, Component.translatable(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY));
}
@Override

View File

@@ -4,10 +4,8 @@ package li.cil.oc2.client.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import li.cil.oc2.client.gui.terminal.TerminalInput;
import li.cil.oc2.client.renderer.MonitorGUIRenderer;
import li.cil.oc2.common.bus.device.vm.block.MonitorDevice;
import li.cil.oc2.common.container.AbstractMachineTerminalContainer;
import li.cil.oc2.common.container.AbstractMonitorContainer;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.MonitorInputMessage;
@@ -23,10 +21,6 @@ import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFW;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import static dev.architectury.utils.GameInstance.getClient;
import static java.awt.SystemColor.menu;
@OnlyIn(Dist.CLIENT)
public final class MonitorDisplayWidget {
@@ -47,14 +41,12 @@ public final class MonitorDisplayWidget {
private int leftPos, topPos;
private boolean isMouseOverTerminal;
private MonitorGUIRenderer.RendererView rendererView;
private MonitorGUIRenderer monitor;
///////////////////////////////////////////////////////////////////
public MonitorDisplayWidget(final AbstractMonitorDisplayScreen<?> parent) {
this.parent = parent;
this.container = this.parent.getMenu();
this.monitor = new MonitorGUIRenderer();
}
public void renderBackground(final GuiGraphics graphics, final int mouseX, final int mouseY) {
@@ -68,18 +60,18 @@ public final class MonitorDisplayWidget {
}
public void render(final GuiGraphics graphics, final int mouseX, final int mouseY, @Nullable final Component error) {
if (container.getPowerState() && container.isMounted()) {
if (container.getPowerState() && container.isMounted() && container.hasPower()) {
final PoseStack terminalStack = new PoseStack();
terminalStack.translate(leftPos + TERMINAL_X, topPos + TERMINAL_Y, 0);
terminalStack.scale((Sprites.TERMINAL_SCREEN.width - 16f) / MonitorDevice.WIDTH, (Sprites.TERMINAL_SCREEN.height - 16f) / MonitorDevice.HEIGHT, 1f);
if (rendererView == null) {
rendererView = monitor.getRenderer(container.getMonitor());
rendererView = container.getMonitor().getMonitor().getRenderer(container.getMonitor());
}
final Matrix4f projectionMatrix = (new Matrix4f()).setOrtho(0, parent.width, parent.height, 0, -10f, 10f);
rendererView.render(terminalStack, projectionMatrix, MonitorDevice.WIDTH, MonitorDevice.HEIGHT);
} else {
} else if (container.getPowerState()) {
final Font font = getClient().font;
if (error != null) {
final int textWidth = font.width(error);
@@ -147,7 +139,6 @@ public final class MonitorDisplayWidget {
if (KeyCodeMapping.MAPPING.containsKey(keycode)) {
final int evdevCode = KeyCodeMapping.MAPPING.get(keycode);
Network.sendToServer(new MonitorInputMessage(container.getMonitor(), evdevCode, isDown));
System.out.println("SENDING KEY");
}
}

View File

@@ -5,22 +5,16 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalNotification;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import li.cil.oc2.api.API;
import li.cil.oc2.common.blockentity.MonitorBlockEntity;
import li.cil.oc2.common.blockentity.ProjectorBlockEntity;
import li.cil.oc2.common.bus.device.vm.block.MonitorDevice;
import li.cil.oc2.common.bus.device.vm.block.ProjectorDevice;
import li.cil.oc2.common.vm.Terminal;
import li.cil.oc2.jcodec.common.model.Picture;
import li.cil.oc2.jcodec.scale.Yuv420jToRgb;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.joml.Matrix4f;
@@ -31,7 +25,6 @@ import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
public class MonitorGUIRenderer {
private final transient Set<RendererModel> renderers = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
@@ -43,6 +36,14 @@ public class MonitorGUIRenderer {
return renderer;
}
@OnlyIn(Dist.CLIENT)
public void releaseRenderer(final MonitorGUIRenderer.RendererView renderer) {
if (renderer instanceof final MonitorGUIRenderer.RendererModel rendererModel) {
rendererModel.close();
renderers.remove(rendererModel);
}
}
private static void handleProjectorNoLongerRendering(final RemovalNotification<MonitorBlockEntity, Renderer.RenderInfo> notification) {
final MonitorBlockEntity monitor = notification.getKey();
if (monitor != null) {
@@ -68,6 +69,7 @@ public class MonitorGUIRenderer {
private static final class Renderer implements RendererModel, RendererView {
private record RenderInfo(DynamicTexture texture) implements ProjectorBlockEntity.FrameConsumer {
private static final ThreadLocal<byte[]> RGB = ThreadLocal.withInitial(() -> new byte[3]);
private static boolean HasRun = true;
public synchronized void close() {
texture.close();
@@ -87,17 +89,17 @@ public class MonitorGUIRenderer {
// Convert in quads, based on the half resolution of UV. As such, skip every other row, since
// we're setting the current and the next.
int lumaIndex = 0, chromaIndex = 0;
for (int halfRow = 0; halfRow < ProjectorDevice.HEIGHT / 2; halfRow++, lumaIndex += ProjectorDevice.WIDTH * 2) {
for (int halfRow = 0; halfRow < MonitorDevice.HEIGHT / 2; halfRow++, lumaIndex += MonitorDevice.WIDTH * 2) {
final int row = halfRow * 2;
for (int halfCol = 0; halfCol < ProjectorDevice.WIDTH / 2; halfCol++, chromaIndex++) {
for (int halfCol = 0; halfCol < MonitorDevice.WIDTH / 2; halfCol++, chromaIndex++) {
final int col = halfCol * 2;
final int yIndex = lumaIndex + col;
final byte cb = u[chromaIndex];
final byte cr = v[chromaIndex];
setFromYUV420(image, col, row, y[yIndex], cb, cr);
setFromYUV420(image, col + 1, row, y[yIndex + 1], cb, cr);
setFromYUV420(image, col, row + 1, y[yIndex + ProjectorDevice.WIDTH], cb, cr);
setFromYUV420(image, col + 1, row + 1, y[yIndex + ProjectorDevice.WIDTH + 1], cb, cr);
setFromYUV420(image, col, row + 1, y[yIndex + MonitorDevice.WIDTH], cb, cr);
setFromYUV420(image, col + 1, row + 1, y[yIndex + MonitorDevice.WIDTH + 1], cb, cr);
}
}

View File

@@ -12,12 +12,12 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import li.cil.oc2.api.API;
import li.cil.oc2.client.renderer.ModRenderType;
import li.cil.oc2.common.block.ComputerBlock;
import li.cil.oc2.client.renderer.MonitorGUIRenderer;
import li.cil.oc2.common.Constants;
import li.cil.oc2.common.block.MonitorBlock;
import li.cil.oc2.common.blockentity.ComputerBlockEntity;
import li.cil.oc2.common.blockentity.MonitorBlockEntity;
import li.cil.oc2.common.bus.device.vm.block.MonitorDevice;
import li.cil.oc2.common.util.ChainableVertexConsumer;
import li.cil.oc2.common.vm.Terminal;
import net.minecraft.client.gui.Font;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
@@ -51,7 +51,7 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
private static final Material TEXTURE_STATUS = new Material(InventoryMenu.BLOCK_ATLAS, OVERLAY_STATUS_LOCATION);
private static final Material TEXTURE_TERMINAL = new Material(InventoryMenu.BLOCK_ATLAS, OVERLAY_TERMINAL_LOCATION);
private static final Cache<Terminal, Terminal.RendererView> rendererViews = CacheBuilder.newBuilder()
private static final Cache<MonitorGUIRenderer, MonitorGUIRenderer.RendererView> rendererViews = CacheBuilder.newBuilder()
.expireAfterAccess(Duration.ofSeconds(5))
.removalListener(MonitorRenderer::handleNoLongerRendering)
.build();
@@ -96,9 +96,9 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
final float pixelScale = 1 / 16f;
stack.scale(pixelScale, pixelScale, pixelScale);
if (false) {
//renderTerminal(monitor, stack, bufferSource, cameraPosition);
} else {
if (monitor.getPowerState() && monitor.isMounted() && monitor.hasPower()) {
renderTerminal(monitor, stack, bufferSource, cameraPosition);
} else if (monitor.getPowerState()) {
renderStatusText(monitor, stack, cameraPosition);
}
@@ -106,30 +106,31 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
final Matrix4f matrix = stack.last().pose();
renderStatus(matrix, bufferSource);
renderPower(matrix, bufferSource);
stack.popPose();
}
///////////////////////////////////////////////////////////////////
/*private void renderTerminal(final MonitorBlockEntity computer, final PoseStack stack, final MultiBufferSource bufferSource, final Vec3 cameraPosition) {
private void renderTerminal(final MonitorBlockEntity monitor, final PoseStack stack, final MultiBufferSource bufferSource, final Vec3 cameraPosition) {
// Render terminal content if close enough.
if (Vec3.atCenterOf(computer.getBlockPos()).closerThan(cameraPosition, 6f)) {
if (Vec3.atCenterOf(monitor.getBlockPos()).closerThan(cameraPosition, 6f)) {
stack.pushPose();
stack.translate(2, 2, -0.9f);
// Scale to make terminal fit fully.
final Terminal terminal = computer.getTerminal();
final float textScaleX = 12f / terminal.getWidth();
final float textScaleY = 7f / terminal.getHeight();
final MonitorGUIRenderer terminal = monitor.getMonitor();
final float textScaleX = 12f / MonitorDevice.WIDTH;
final float textScaleY = 9f / MonitorDevice.HEIGHT;
final float scale = Math.min(textScaleX, textScaleY) * 0.95f;
// Center it on both axes.
final float scaleDeltaX = textScaleX - scale;
final float scaleDeltaY = textScaleY - scale;
stack.translate(
terminal.getWidth() * scaleDeltaX * 0.5f,
terminal.getHeight() * scaleDeltaY * 0.5f,
MonitorDevice.WIDTH * scaleDeltaX * 0.5f,
MonitorDevice.HEIGHT * scaleDeltaY * 0.5f,
0f);
stack.scale(scale, scale, 1f);
@@ -139,7 +140,7 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
RenderSystem.enableDepthTest();
try {
rendererViews.get(terminal, terminal::getRenderer).render(stack, RenderSystem.getProjectionMatrix());
rendererViews.get(terminal, () -> terminal.getRenderer(monitor)).render(stack, RenderSystem.getProjectionMatrix(), MonitorDevice.WIDTH, MonitorDevice.HEIGHT);
} catch (final ExecutionException e) {
throw new RuntimeException(e);
}
@@ -154,14 +155,14 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
stack.popPose();
}
}*/
}
private void renderStatusText(final MonitorBlockEntity monitor, final PoseStack stack, final Vec3 cameraPosition) {
if (!Vec3.atCenterOf(monitor.getBlockPos()).closerThan(cameraPosition, 12f)) {
return;
}
final Component bootError = Component.literal("RENDERING");
final Component bootError = Component.translatable(Constants.COMPUTER_ERROR_NOT_ENOUGH_ENERGY);
stack.pushPose();
stack.translate(3, 3, -0.9f);
@@ -241,9 +242,9 @@ public final class MonitorRenderer implements BlockEntityRenderer<MonitorBlockEn
rendererViews.cleanUp();
}
private static void handleNoLongerRendering(final RemovalNotification<Terminal, Terminal.RendererView> notification) {
final Terminal key = notification.getKey();
final Terminal.RendererView value = notification.getValue();
private static void handleNoLongerRendering(final RemovalNotification<MonitorGUIRenderer, MonitorGUIRenderer.RendererView> notification) {
final MonitorGUIRenderer key = notification.getKey();
final MonitorGUIRenderer.RendererView value = notification.getValue();
if (key != null && value != null) {
key.releaseRenderer(value);
}

View File

@@ -49,9 +49,9 @@ public final class MonitorBlock extends HorizontalDirectionalBlock implements En
private static final VoxelShape NEG_Z_SHAPE = Shapes.or(
Block.box(0, 0, 1, 16, 16, 16), // main body
Block.box(0, 15, 0, 16, 16, 1), // across top
Block.box(0, 0, 0, 16, 6, 1), // across bottom
Block.box(0, 0, 0, 1, 16, 1), // up left
Block.box(15, 0, 0, 16, 16, 1) // up right
Block.box(0, 0, 0, 16, 4, 1), // across bottom
Block.box(0, 0, 0, 2, 16, 1), // up left
Block.box(14, 0, 0, 16, 16, 1) // up right
);
private static final VoxelShape NEG_X_SHAPE = VoxelShapeUtils.rotateHorizontalClockwise(NEG_Z_SHAPE);
private static final VoxelShape POS_Z_SHAPE = VoxelShapeUtils.rotateHorizontalClockwise(NEG_X_SHAPE);

View File

@@ -2,35 +2,19 @@
package li.cil.oc2.common.blockentity;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.bus.device.Device;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
import li.cil.oc2.api.capabilities.TerminalUserProvider;
import li.cil.oc2.client.audio.LoopingSoundManager;
import li.cil.oc2.client.renderer.MonitorGUIRenderer;
import li.cil.oc2.common.Config;
import li.cil.oc2.common.block.ComputerBlock;
import li.cil.oc2.common.block.ProjectorBlock;
import li.cil.oc2.common.bus.AbstractBlockDeviceBusElement;
import li.cil.oc2.common.bus.BlockDeviceBusController;
import li.cil.oc2.common.bus.CommonDeviceBusController;
import li.cil.oc2.common.bus.device.BlockDeviceBusElement;
import li.cil.oc2.common.bus.device.util.Devices;
import li.cil.oc2.common.bus.device.vm.block.KeyboardDevice;
import li.cil.oc2.common.bus.device.vm.block.MonitorDevice;
import li.cil.oc2.common.bus.device.vm.block.ProjectorDevice;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.container.ComputerInventoryContainer;
import li.cil.oc2.common.container.ComputerTerminalContainer;
import li.cil.oc2.common.container.MonitorDisplayContainer;
import li.cil.oc2.common.energy.FixedEnergyStorage;
import li.cil.oc2.common.network.MonitorLoadBalancer;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.ProjectorLoadBalancer;
import li.cil.oc2.common.network.message.*;
import li.cil.oc2.common.serialization.NBTSerialization;
import li.cil.oc2.common.util.*;
import li.cil.oc2.common.vm.*;
import li.cil.oc2.common.vm.device.SimpleFramebufferDevice;
import li.cil.oc2.jcodec.codecs.h264.H264Decoder;
import li.cil.oc2.jcodec.codecs.h264.H264Encoder;
import li.cil.oc2.jcodec.codecs.h264.encode.CQPRateControl;
@@ -39,26 +23,14 @@ import li.cil.oc2.jcodec.common.model.Picture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -68,8 +40,8 @@ import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import static li.cil.oc2.common.Constants.BLOCK_ENTITY_TAG_NAME_IN_ITEM;
import static li.cil.oc2.common.Constants.ITEMS_TAG_NAME;
import static li.cil.oc2.common.bus.device.vm.block.MonitorDevice.HEIGHT;
import static li.cil.oc2.common.bus.device.vm.block.MonitorDevice.WIDTH;
public final class MonitorBlockEntity extends ModBlockEntity implements TickableBlockEntity {
private static final String STATE_TAG_NAME = "state";
@@ -96,17 +68,18 @@ public final class MonitorBlockEntity extends ModBlockEntity implements Tickable
@Nullable private CompletableFuture<?> runningDecode;
private final H264Decoder decoder = new H264Decoder();
private final ByteBuffer decoderBuffer = ByteBuffer.allocateDirect(1024 * 1024);
private final ByteBuffer decoderBuffer = ByteBuffer.allocateDirect(WIDTH * HEIGHT * SimpleFramebufferDevice.STRIDE);
@Nullable private ProjectorBlockEntity.FrameConsumer frameConsumer;
private boolean needsIDR;
private final BlockDeviceBusElement busElement = new BlockDeviceBusElement();
private final MonitorDevice monitorDevice = new MonitorDevice(this, this::handleMountedChanged);
private final KeyboardDevice<BlockEntity> keyboardDevice = new KeyboardDevice<>(this);
private final Picture picture = Picture.create(MonitorDevice.WIDTH, MonitorDevice.HEIGHT, ColorSpace.YUV420J);
private final Picture picture = Picture.create(WIDTH, HEIGHT, ColorSpace.YUV420J);
private final MonitorGUIRenderer monitor = new MonitorGUIRenderer();
private final H264Encoder encoder = new H264Encoder(new CQPRateControl(12));
private final ByteBuffer encoderBuffer = ByteBuffer.allocateDirect(1024 * 1024);
private final ByteBuffer encoderBuffer = ByteBuffer.allocateDirect(WIDTH * HEIGHT * SimpleFramebufferDevice.STRIDE);
///////////////////////////////////////////////////////////////////
@@ -115,10 +88,17 @@ public final class MonitorBlockEntity extends ModBlockEntity implements Tickable
needsIDR = true;
}
public boolean hasPower() {
return true;
//return energy.extractEnergy(Config.projectorEnergyPerTick, true) >= Config.projectorEnergyPerTick || !Config.projectorsUseEnergy();
}
public boolean getPowerState() { return isPowered; }
public boolean isMounted() { return isMounted; }
public MonitorGUIRenderer getMonitor() { return monitor; }
private long lastKeepAliveSentAt;
public void handleInput(final int keycode, final boolean isDown) {
@@ -300,7 +280,6 @@ public final class MonitorBlockEntity extends ModBlockEntity implements Tickable
tag.putBoolean(IS_PROJECTING_TAG_NAME, isMounted);
tag.putBoolean(HAS_ENERGY_TAG_NAME, hasEnergy);
tag.putBoolean(STATE_TAG_NAME, isPowered);
return tag;
}

View File

@@ -27,7 +27,7 @@ public final class ProjectorDevice extends IdentityProxy<BlockEntity> implements
private static final String BLOB_HANDLE_TAG_NAME = "blob";
public static final int WIDTH = 640;
public static final int HEIGHT = 480;
public static final int HEIGHT = 360;
///////////////////////////////////////////////////////////////

View File

@@ -3,12 +3,10 @@
package li.cil.oc2.common.container;
import li.cil.oc2.common.block.Blocks;
import li.cil.oc2.common.blockentity.ComputerBlockEntity;
import li.cil.oc2.common.blockentity.MonitorBlockEntity;
import li.cil.oc2.common.bus.CommonDeviceBusController;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.*;
import li.cil.oc2.common.vm.Terminal;
import li.cil.oc2.common.vm.VirtualMachine;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ContainerLevelAccess;
@@ -17,7 +15,6 @@ import net.minecraft.world.level.Level;
import net.minecraftforge.energy.IEnergyStorage;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
public abstract class AbstractMonitorContainer extends AbstractMachineContainer {
private final MonitorBlockEntity monitor;
@@ -38,7 +35,9 @@ public abstract class AbstractMonitorContainer extends AbstractMachineContainer
@Nullable
public VirtualMachine getVirtualMachine() { return null; }
public MonitorBlockEntity getMonitor() { return monitor; };
public MonitorBlockEntity getMonitor() { return monitor; }
public boolean hasPower() { return monitor.hasPower(); }
public boolean getPowerState() { return monitor.getPowerState(); }

View File

@@ -68,7 +68,8 @@ public final class SimpleFramebufferDevice implements MemoryMappedDevice {
}
synchronized (buffer) {
final int[][] quadrant = conversionBuffer.get();
convertR5G6B5ToYUV420J(buffer, width, height, picture);
/*final int[][] quadrant = conversionBuffer.get();
final byte[][] pictureData = picture.getData();
for (int halfRow = dirtyLines.nextSetBit(0); halfRow >= 0; halfRow = dirtyLines.nextSetBit(halfRow + 1)) {
dirtyLines.clear(halfRow);
@@ -92,12 +93,55 @@ public final class SimpleFramebufferDevice implements MemoryMappedDevice {
pictureData[1][chromaIndex] = (byte) ((quadrant[0][1] + quadrant[1][1] + quadrant[2][1] + quadrant[3][1] + 2) >> 2);
pictureData[2][chromaIndex] = (byte) ((quadrant[0][2] + quadrant[1][2] + quadrant[2][2] + quadrant[3][2] + 2) >> 2);
}
}
}*/
}
return true;
}
public static void convertR5G6B5ToYUV420J(ByteBuffer rgbBuffer, int width, int height, Picture yuvPicture) {
// Retrieve the YUV planes from the Picture object
byte[][] yuvData = yuvPicture.getData();
byte[] yPlane = yuvData[0];
byte[] uPlane = yuvData[1];
byte[] vPlane = yuvData[2];
int uvWidth = width / 2;
// Iterate through each pixel
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int index = j * width + i;
// Extract pixel data from ByteBuffer
short pixel = rgbBuffer.getShort(index * 2);
// Extract R, G, B from R5G6B5 with correct endianness
final int r5 = (pixel >>> 11) & 0b11111;
final int g6 = (pixel >>> 5) & 0b111111;
final int b5 = pixel & 0b11111;
final byte r = (byte) ((r5 * 255 / 0b11111) - 128);
final byte g = (byte) ((g6 * 255 / 0b111111) - 128);
final byte b = (byte) ((b5 * 255 / 0b11111) - 128);
int[] yuv = new int[3];
RgbToYuv420j.rgb2yuv(r, g, b, yuv);
// Set Y plane
yPlane[index] = (byte) yuv[0];
// Set U and V planes (subsampled)
if (j % 2 == 0 && i % 2 == 0) {
int uvIndex = (j / 2) * uvWidth + (i / 2);
uPlane[uvIndex] = (byte) yuv[1];
vPlane[uvIndex] = (byte) yuv[2];
}
}
}
}
@Override
public int getLength() {
return length;
@@ -134,17 +178,6 @@ public final class SimpleFramebufferDevice implements MemoryMappedDevice {
///////////////////////////////////////////////////////////////
private static void r5g6b5ToYuv420(final int r5g6b5, final int[] yuv) {
final int r5 = (r5g6b5 >>> 11) & 0b11111;
final int g6 = (r5g6b5 >>> 5) & 0b111111;
final int b5 = r5g6b5 & 0b11111;
final byte r = (byte) ((r5 * 255 / 0b11111) - 128);
final byte g = (byte) ((g6 * 255 / 0b111111) - 128);
final byte b = (byte) ((b5 * 255 / 0b11111) - 128);
RgbToYuv420j.rgb2yuv(r, g, b, yuv);
}
private void setDirty(final int offset) {
final int pixelY = offset / (width * STRIDE);
dirtyLines.set(pixelY / 2);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
# Made in Blockbench 4.10.1
newmtl m_0a3fa02d-dcdc-7e71-1268-ac9e30245601
map_Kd #texture0
newmtl none

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

File diff suppressed because one or more lines are too long