From f395b13a3697b867a03ccfc16122dfc5cf495236 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 6 Aug 2025 21:06:40 -0400 Subject: [PATCH 1/3] Make logic analog --- .../logic/renderer/OnOffLogicRenderer.java | 2 +- .../gui/microchip/wire/WireEndpoints.java | 4 +-- .../element/WireElementTagCompiler.java | 2 +- .../microchip/Microchip.java | 7 ++-- .../object/logic/LogicComponent.java | 8 ++--- .../object/logic/config/LogicConfig.java | 8 ++--- .../object/logic/debug/LogicDebugger.java | 6 ++-- .../object/logic/gate/LogicGate.java | 17 ++++++---- .../microchip/object/logic/io/LogicIO.java | 27 +++++++-------- .../object/logic/latch/rs/RSNORLatch.java | 32 ++++++++--------- .../logic/latch/tflipflop/TFlipFlop.java | 27 ++++++++------- .../object/logic/pulse/PulseThrottler.java | 34 +++++++++---------- .../logic/randomizer/LogicRandomizer.java | 29 ++++++++++------ .../object/logic/reader/LogicReader.java | 8 ++--- .../object/logic/selector/LogicSelector.java | 34 +++++++++++++------ .../logic/sequencer/LogicSequencer.java | 25 +++++++++----- 16 files changed, 152 insertions(+), 118 deletions(-) diff --git a/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/OnOffLogicRenderer.java b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/OnOffLogicRenderer.java index b7be48a1..8dd9d76e 100644 --- a/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/OnOffLogicRenderer.java +++ b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/OnOffLogicRenderer.java @@ -22,7 +22,7 @@ public void render(Context context, TesseractGuiGraphics graphics, L component, (shader) -> shader.getUniform("LogicUV").set(16f, 16f) ); graphics.setTextures( - context.getTexture(component.output(0) ? "on" : "off"), + context.getTexture(component.output(0) > 0 ? "on" : "off"), LBR.id("textures/logic/scanline.png") ); int centerX = x + size.centerX() - 8; diff --git a/src/main/java/net/swedz/little_big_redstone/gui/microchip/wire/WireEndpoints.java b/src/main/java/net/swedz/little_big_redstone/gui/microchip/wire/WireEndpoints.java index 635e3ffa..75a389ac 100644 --- a/src/main/java/net/swedz/little_big_redstone/gui/microchip/wire/WireEndpoints.java +++ b/src/main/java/net/swedz/little_big_redstone/gui/microchip/wire/WireEndpoints.java @@ -50,7 +50,7 @@ private static WireEndpoints of(int outputX, int outputY, LogicComponent o input.size().wireInEndX(inputX), input.size().wireInEndY(inputY, inputIndex, input.inputs()), usePadding, - output.output(outputIndex), + output.output(outputIndex) > 0, getColor(output, fallbackColor) ); } @@ -127,7 +127,7 @@ public static WireEndpoints heldWire(MicrochipWidgetContext context) startX, startY, context.boardMouseX() + 1, context.boardMouseY() - 1, false, - outputLogic.component().output(selectedPort.index()), + outputLogic.component().output(selectedPort.index()) > 0, getColor(outputLogic.component(), context.widget().color()) ); } diff --git a/src/main/java/net/swedz/little_big_redstone/guide/tags/microchip/element/WireElementTagCompiler.java b/src/main/java/net/swedz/little_big_redstone/guide/tags/microchip/element/WireElementTagCompiler.java index ef03bb4a..8e74492e 100644 --- a/src/main/java/net/swedz/little_big_redstone/guide/tags/microchip/element/WireElementTagCompiler.java +++ b/src/main/java/net/swedz/little_big_redstone/guide/tags/microchip/element/WireElementTagCompiler.java @@ -36,7 +36,7 @@ public void compile(MicrochipGuidebookScene microchip, PageCompiler compiler, Ly int fromPort = MdxAttrs.getInt(compiler, errorSink, el, "fromPort", 0); int toPort = MdxAttrs.getInt(compiler, errorSink, el, "toPort", 0); - Boolean powerLock = el.getAttribute("powered") == null ? null : MdxAttrs.getBoolean(compiler, errorSink, el, "powered", false); + Integer powerLock = el.getAttribute("powered") == null ? null : MdxAttrs.getInt(compiler, errorSink, el, "powered", 0); microchip.addWire(from, to, fromPort, toPort, compiler, errorSink, el); diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/Microchip.java b/src/main/java/net/swedz/little_big_redstone/microchip/Microchip.java index 9cbb8c5e..c4adc2f8 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/Microchip.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/Microchip.java @@ -221,7 +221,7 @@ public void tickLogic(LogicContext context) { int inputSlot = entry.slot(); int totalInputs = entry.component().inputs(); - boolean[] inputs = new boolean[totalInputs]; + int[] inputs = new int[totalInputs]; outer: for(int inputPort = 0; inputPort < totalInputs; inputPort++) { @@ -229,9 +229,10 @@ public void tickLogic(LogicContext context) { if(wire.input().index() == inputPort) { - if(components.get(wire.output().slot()).component().output(wire.output().index())) + int signal = components.get(wire.output().slot()).component().output(wire.output().index()); + if(signal > 0) { - inputs[inputPort] = true; + inputs[inputPort] = signal; continue outer; } } diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicComponent.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicComponent.java index e73e168a..d718e27e 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicComponent.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicComponent.java @@ -82,9 +82,9 @@ public final int outputs() return config.outputs(); } - protected abstract void processTickInternal(LogicContext context, boolean[] inputs); + protected abstract void processTickInternal(LogicContext context, int[] inputs); - public final void processTick(LogicContext context, boolean[] inputs) + public final void processTick(LogicContext context, int[] inputs) { int expectedInputs = this.inputs(); Assert.that(expectedInputs == inputs.length, "Mismatching logic component input sizes: expected %d but got %d".formatted(expectedInputs, inputs.length)); @@ -94,9 +94,9 @@ public final void processTick(LogicContext context, boolean[] inputs) } } - protected abstract boolean outputInternal(int index); + protected abstract int outputInternal(int index); - public final boolean output(int index) + public final int output(int index) { var lock = config.getOutputLock(index); if(lock != null) diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/config/LogicConfig.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/config/LogicConfig.java index 221213ae..2ad57326 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/config/LogicConfig.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/config/LogicConfig.java @@ -17,7 +17,7 @@ public abstract class LogicConfig> implements LogicPort * WARNING: Should not be used at all outside of the guide. Ever. If this is not null for a logic component * outside of the guide, something has gone terribly wrong. */ - protected Boolean[] outputLocks; + protected Integer[] outputLocks; /** * Used to hide logic in the guide so that only the wires to/from it render. @@ -42,16 +42,16 @@ protected boolean calculateValidity(LogicComponents components) return true; } - public final void setOutputLock(int index, Boolean lock) + public final void setOutputLock(int index, Integer lock) { if(outputLocks == null || outputLocks.length <= index) { - outputLocks = outputLocks == null ? new Boolean[index + 1] : Arrays.copyOf(outputLocks, index + 1); + outputLocks = outputLocks == null ? new Integer[index + 1] : Arrays.copyOf(outputLocks, index + 1); } outputLocks[index] = lock; } - public final Boolean getOutputLock(int index) + public final Integer getOutputLock(int index) { return (outputLocks == null || outputLocks.length <= index) ? null : outputLocks[index]; } diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/debug/LogicDebugger.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/debug/LogicDebugger.java index 95e0f879..47e60436 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/debug/LogicDebugger.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/debug/LogicDebugger.java @@ -50,14 +50,14 @@ public LogicType type() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { - return false; + return 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/gate/LogicGate.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/gate/LogicGate.java index 61c305c2..f2ae4d7b 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/gate/LogicGate.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/gate/LogicGate.java @@ -75,10 +75,15 @@ protected LogicGate(Optional color, boolean outputState) protected abstract boolean processInputs(LogicContext context, boolean[] inputs); @Override - public final void processTickInternal(LogicContext context, boolean[] inputs) + public final void processTickInternal(LogicContext context, int[] inputs) { boolean originalOutputState = outputState; - outputState = this.processInputs(context, inputs); + boolean[] inputsBinary = new boolean[inputs.length]; + for(int index = 0; index < inputs.length; index++) + { + inputsBinary[index] = inputs[index] > 0; + } + outputState = this.processInputs(context, inputsBinary); if(outputState != originalOutputState) { context.markDirty(this); @@ -86,14 +91,14 @@ public final void processTickInternal(LogicContext context, boolean[] inputs) } @Override - protected final boolean outputInternal(int index) + protected final int outputInternal(int index) { - return outputState; + return outputState ? 1 : 0; } public final boolean output() { - return this.output(0); + return this.output(0) > 0; } @Override @@ -106,7 +111,7 @@ public LogicGridSize size() @Override protected void internalLoadFrom(G other) { - outputState = other.outputInternal(0); + outputState = other.outputInternal(0) > 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/io/LogicIO.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/io/LogicIO.java index 640cd6fe..8d1a29ce 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/io/LogicIO.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/io/LogicIO.java @@ -29,26 +29,26 @@ public final class LogicIO extends LogicComponent implem .group( LogicIOConfig.CODEC.fieldOf("config").forGetter(LogicIO::config), DyeColor.CODEC.optionalFieldOf("color").forGetter(LogicIO::color), - Codec.BOOL.optionalFieldOf("output", false).forGetter(LogicIO::output) + Codec.INT.optionalFieldOf("output", 0).forGetter(LogicIO::output) ) .apply(instance, LogicIO::new)); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( LogicIOConfig.STREAM_CODEC, LogicIO::config, ByteBufCodecs.optional(DyeColor.STREAM_CODEC), LogicIO::color, - ByteBufCodecs.BOOL, LogicIO::output, + ByteBufCodecs.VAR_INT, LogicIO::output, LogicIO::new ); - private boolean outputState; + private int outputState; - private LogicIO(LogicIOConfig config, Optional color, boolean outputState) + private LogicIO(LogicIOConfig config, Optional color, int outputState) { super(config, color); this.outputState = outputState; } - private LogicIO(Optional color, boolean outputState) + private LogicIO(Optional color, int outputState) { super(color); this.outputState = outputState; @@ -56,7 +56,7 @@ private LogicIO(Optional color, boolean outputState) public LogicIO() { - this(Optional.empty(), false); + this(Optional.empty(), 0); } @Override @@ -74,21 +74,20 @@ protected LogicIOConfig defaultConfig() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { boolean powerChanged = false; - boolean originalOutputState = outputState; + int originalOutputState = outputState; if(config.input) { int signal = context.awareness(AwarenessTypes.REDSTONE).getInputPower(config.direction); - outputState = config.signalComparison.test(signal, config.signalStrength); + outputState = config.signalComparison.test(signal, config.signalStrength) ? signal : 0; } else { outputState = inputs[0]; var redstone = context.awareness(AwarenessTypes.REDSTONE); - int signal = outputState ? config.signalStrength : 0; - if(redstone.setOutputPowered(config.direction, signal)) + if(redstone.setOutputPowered(config.direction, outputState)) { powerChanged = true; } @@ -106,12 +105,12 @@ public LogicType type() } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { return outputState; } - public boolean output() + public int output() { return this.output(0); } @@ -132,7 +131,7 @@ protected void internalLoadFrom(LogicIO other) @Override public void internalResetForPickup() { - outputState = false; + outputState = 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/rs/RSNORLatch.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/rs/RSNORLatch.java index c830d782..183f5a21 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/rs/RSNORLatch.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/rs/RSNORLatch.java @@ -25,19 +25,19 @@ public final class RSNORLatch extends LogicComponent CODEC = RecordCodecBuilder.mapCodec((instance) -> instance .group( DyeColor.CODEC.optionalFieldOf("color").forGetter(RSNORLatch::color), - Codec.BOOL.optionalFieldOf("output", false).forGetter(RSNORLatch::output) + Codec.INT.optionalFieldOf("output", 0).forGetter(RSNORLatch::output) ) .apply(instance, RSNORLatch::new)); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.optional(DyeColor.STREAM_CODEC), RSNORLatch::color, - ByteBufCodecs.BOOL, RSNORLatch::output, + ByteBufCodecs.VAR_INT, RSNORLatch::output, RSNORLatch::new ); - private boolean outputState; + private int outputState; - private RSNORLatch(Optional color, boolean outputState) + private RSNORLatch(Optional color, int outputState) { super(color); this.outputState = outputState; @@ -45,7 +45,7 @@ private RSNORLatch(Optional color, boolean outputState) public RSNORLatch() { - this(Optional.empty(), false); + this(Optional.empty(), 0); } @Override @@ -61,19 +61,19 @@ public LogicType type() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { - boolean originalOutputState = outputState; - boolean set = inputs[0]; - boolean reset = inputs[1]; + int originalOutputState = outputState; + int set = inputs[0]; + int reset = inputs[1]; - if(reset) + if(reset > 0) { - outputState = false; + outputState = 0; } - else if(set) + else if(set > 0) { - outputState = true; + outputState = set; } if(originalOutputState != outputState) @@ -83,12 +83,12 @@ else if(set) } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { return outputState; } - public boolean output() + public int output() { return this.output(0); } @@ -109,7 +109,7 @@ protected void internalLoadFrom(RSNORLatch other) @Override protected void internalResetForPickup() { - outputState = false; + outputState = 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/tflipflop/TFlipFlop.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/tflipflop/TFlipFlop.java index c257e5a6..c820c0de 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/tflipflop/TFlipFlop.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/latch/tflipflop/TFlipFlop.java @@ -26,20 +26,21 @@ public final class TFlipFlop extends LogicComponent .group( DyeColor.CODEC.optionalFieldOf("color").forGetter(TFlipFlop::color), Codec.BOOL.optionalFieldOf("last_input", false).forGetter(TFlipFlop::lastInput), - Codec.BOOL.optionalFieldOf("output", false).forGetter(TFlipFlop::output) + Codec.INT.optionalFieldOf("output", 0).forGetter(TFlipFlop::output) ) .apply(instance, TFlipFlop::new)); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.optional(DyeColor.STREAM_CODEC), TFlipFlop::color, ByteBufCodecs.BOOL, TFlipFlop::lastInput, - ByteBufCodecs.BOOL, TFlipFlop::output, + ByteBufCodecs.VAR_INT, TFlipFlop::output, TFlipFlop::new ); - private boolean lastInputState, outputState; + private boolean lastInputState; + private int outputState; - private TFlipFlop(Optional color, boolean lastInputState, boolean outputState) + private TFlipFlop(Optional color, boolean lastInputState, int outputState) { super(color); this.lastInputState = lastInputState; @@ -48,7 +49,7 @@ private TFlipFlop(Optional color, boolean lastInputState, boolean outp public TFlipFlop() { - this(Optional.empty(), false, false); + this(Optional.empty(), false, 0); } @Override @@ -64,17 +65,17 @@ public LogicType type() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { - boolean input = inputs[0]; + int input = inputs[0]; - if(!lastInputState && input) + if(!lastInputState && input > 0) { - outputState = !outputState; + outputState = outputState > 0 ? 0 : input; context.markDirty(this); } - lastInputState = input; + lastInputState = input > 0; } public boolean lastInput() @@ -83,12 +84,12 @@ public boolean lastInput() } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { return outputState; } - public boolean output() + public int output() { return this.output(0); } @@ -110,7 +111,7 @@ protected void internalLoadFrom(TFlipFlop other) public void internalResetForPickup() { lastInputState = false; - outputState = false; + outputState = 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/pulse/PulseThrottler.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/pulse/PulseThrottler.java index 511e206c..b1c2ffdd 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/pulse/PulseThrottler.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/pulse/PulseThrottler.java @@ -28,7 +28,7 @@ public final class PulseThrottler extends LogicComponent color, boolean lastInputState, long processedTicks, boolean outputState) + private PulseThrottler(PulseThrottlerConfig config, Optional color, boolean lastInputState, long processedTicks, int outputState) { super(config, color); this.lastInputState = lastInputState; @@ -54,7 +54,7 @@ private PulseThrottler(PulseThrottlerConfig config, Optional color, bo this.outputState = outputState; } - private PulseThrottler(Optional color, boolean lastInputState, long processedTicks, boolean outputState) + private PulseThrottler(Optional color, boolean lastInputState, long processedTicks, int outputState) { super(color); this.lastInputState = lastInputState; @@ -64,7 +64,7 @@ private PulseThrottler(Optional color, boolean lastInputState, long pr public PulseThrottler() { - this(Optional.empty(), false, 0, false); + this(Optional.empty(), false, 0, 0); } @Override @@ -90,29 +90,29 @@ public long processedTicks() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { - boolean input = inputs[0]; - boolean output = false; + int input = inputs[0]; + int output = 0; boolean changed = false; if(processedTicks >= config.outputDuration) { processedTicks = 0; - output = false; + output = 0; changed = true; } - else if(!lastInputState && input) + else if(!lastInputState && input > 0) { processedTicks++; - output = true; + output = input; changed = true; } else if(processedTicks > 0) { processedTicks++; - output = true; + output = input; changed = true; } @@ -121,16 +121,16 @@ else if(processedTicks > 0) { context.markDirty(this); } - lastInputState = input; + lastInputState = input > 0; } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { return outputState; } - public boolean output() + public int output() { return this.output(0); } @@ -154,7 +154,7 @@ protected void internalResetForPickup() { lastInputState = false; processedTicks = 0; - outputState = false; + outputState = 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/randomizer/LogicRandomizer.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/randomizer/LogicRandomizer.java index 98e1c661..d5a6912f 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/randomizer/LogicRandomizer.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/randomizer/LogicRandomizer.java @@ -30,34 +30,38 @@ public final class LogicRandomizer extends LogicComponent STREAM_CODEC = StreamCodec.composite( LogicRandomizerConfig.STREAM_CODEC, LogicRandomizer::config, ByteBufCodecs.optional(DyeColor.STREAM_CODEC), LogicRandomizer::color, - ByteBufCodecs.INT, LogicRandomizer::outputIndex, + ByteBufCodecs.VAR_INT, LogicRandomizer::outputIndex, + ByteBufCodecs.VAR_INT, LogicRandomizer::output, LogicRandomizer::new ); - private int outputIndex; + private int outputIndex, outputState; - private LogicRandomizer(LogicRandomizerConfig config, Optional color, int outputIndex) + private LogicRandomizer(LogicRandomizerConfig config, Optional color, int outputIndex, int outputState) { super(config, color); this.outputIndex = outputIndex; + this.outputState = outputState; } - private LogicRandomizer(Optional color, int outputIndex) + private LogicRandomizer(Optional color, int outputIndex, int outputState) { super(color); this.outputIndex = outputIndex; + this.outputState = outputState; } public LogicRandomizer() { - this(Optional.empty(), -1); + this(Optional.empty(), -1, 0); } public int outputIndex() @@ -66,11 +70,11 @@ public int outputIndex() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { int originalOutputIndex = outputIndex; - if(inputs[0] && RANDOM.nextFloat() <= config.chance) + if(inputs[0] > 0 && RANDOM.nextFloat() <= config.chance) { outputIndex = RANDOM.nextInt(config.outputs); } @@ -86,9 +90,14 @@ protected void processTickInternal(LogicContext context, boolean[] inputs) } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { - return index == outputIndex; + return index == outputIndex ? outputState : 0; + } + + public int output() + { + return outputState; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/reader/LogicReader.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/reader/LogicReader.java index ec3e2d87..30794fe6 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/reader/LogicReader.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/reader/LogicReader.java @@ -79,7 +79,7 @@ protected LogicReaderConfig defaultConfig() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { boolean originalOutputState = outputState; @@ -156,14 +156,14 @@ public LogicType type() } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { - return outputState; + return outputState ? 1 : 0; } public boolean output() { - return this.output(0); + return this.output(0) > 0; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java index bcd46c85..88bb7365 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java @@ -27,7 +27,8 @@ public final class LogicSelector extends LogicComponent color, int selected) + private LogicSelector(LogicSelectorConfig config, Optional color, int selected, int outputState) { super(config, color); this.selected = selected; + this.outputState = outputState; } - private LogicSelector(Optional color, int selected) + private LogicSelector(Optional color, int selected, int outputState) { super(color); this.selected = selected; + this.outputState = outputState; } public LogicSelector() { - this(Optional.empty(), 0); + this(Optional.empty(), 0, 0); } public int selected() @@ -63,14 +67,14 @@ public int selected() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { int originalSelected = selected; if(config.mode == LogicSelectorMode.COUNTER) { - boolean decrement = inputs[0]; - boolean increment = inputs[1]; + boolean decrement = inputs[0] > 0; + boolean increment = inputs[1] > 0; int newSelected = selected; if(decrement) { @@ -89,14 +93,17 @@ protected void processTickInternal(LogicContext context, boolean[] inputs) } } selected = newSelected; + outputState = Math.max(inputs[0], inputs[1]); } else if(config.mode == LogicSelectorMode.SETTER) { for(int index = inputs.length - 1; index >= 0; index--) { - if(inputs[index]) + int signal = inputs[index]; + if(signal > 0) { selected = index; + outputState = signal; break; } } @@ -109,9 +116,14 @@ else if(config.mode == LogicSelectorMode.SETTER) } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { - return index == selected; + return index == selected ? outputState : 0; + } + + public int output() + { + return outputState; } @Override diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/sequencer/LogicSequencer.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/sequencer/LogicSequencer.java index a03e80aa..68ce1b55 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/sequencer/LogicSequencer.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/sequencer/LogicSequencer.java @@ -28,6 +28,7 @@ public final class LogicSequencer extends LogicComponent l.lastInput), Codec.BOOL.optionalFieldOf("output", false).forGetter(LogicSequencer::output) ) .apply(instance, LogicSequencer::new)); @@ -36,31 +37,36 @@ public final class LogicSequencer extends LogicComponent l.lastInput, ByteBufCodecs.BOOL, LogicSequencer::output, LogicSequencer::new ); private long processedTicks; + private int lastInput; + private boolean outputState; - private LogicSequencer(LogicSequencerConfig config, Optional color, long processedTicks, boolean outputState) + private LogicSequencer(LogicSequencerConfig config, Optional color, long processedTicks, int lastInput, boolean outputState) { super(config, color); this.processedTicks = processedTicks; + this.lastInput = lastInput; this.outputState = outputState; } - private LogicSequencer(Optional color, long processedTicks, boolean outputState) + private LogicSequencer(Optional color, long processedTicks, int lastInput, boolean outputState) { super(color); this.processedTicks = processedTicks; + this.lastInput = lastInput; this.outputState = outputState; } public LogicSequencer() { - this(Optional.empty(), 0, false); + this(Optional.empty(), 0, 0, false); } @Override @@ -80,19 +86,20 @@ public float processedPercentage() } @Override - protected void processTickInternal(LogicContext context, boolean[] inputs) + protected void processTickInternal(LogicContext context, int[] inputs) { long originalProcessedTicks = processedTicks; boolean originalOutputState = outputState; - boolean input = inputs[0]; + boolean input = inputs[0] > 0; boolean output = false; - if(config.resetPort && inputs[1]) + if(config.resetPort && inputs[1] > 0) { processedTicks = 0; } else { + lastInput = inputs[0]; if(input) { processedTicks++; @@ -130,14 +137,14 @@ public LogicType type() } @Override - protected boolean outputInternal(int index) + protected int outputInternal(int index) { - return outputState; + return outputState ? lastInput : 0; } public boolean output() { - return this.output(0); + return this.output(0) > 0; } @Override From 43d5a4409bb5d6c339189428ce427d18566f2cd9 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 24 Sep 2025 22:19:18 -0400 Subject: [PATCH 2/3] Fix selector not loading output state --- .../microchip/object/logic/selector/LogicSelector.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java index 88bb7365..b4bf30e4 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/selector/LogicSelector.java @@ -143,12 +143,14 @@ public void appendShiftHoverText(List lines) protected void internalLoadFrom(LogicSelector other) { selected = other.selected; + outputState = other.outputState; } @Override protected void internalResetForPickup() { selected = 0; + outputState = 0; } @Override From 344967e4ba98eeb749e02c8799b0c0525329d9a0 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 24 Sep 2025 22:54:23 -0400 Subject: [PATCH 3/3] Add Calculator component --- .../font/logic_component.json | 21 ++- .../little_big_redstone/lang/en_us.json | 6 + .../models/item/calculator.json | 81 ++++++++++ .../recipe/logic/calculator.json | 27 ++++ .../tags/item/logic_components.json | 1 + .../swedz/little_big_redstone/LBRText.java | 5 + .../little_big_redstone/LBRTooltips.java | 7 + .../LogicItemModelsDatagenProvider.java | 9 ++ .../recipes/LogicRecipesDatagenProvider.java | 5 + .../gui/microchip/logic/LogicRenderers.java | 22 +++ .../renderer/CalculatorLogicRenderer.java | 34 +++++ .../microchip/object/logic/LogicTypes.java | 3 + .../object/logic/math/Calculator.java | 121 +++++++++++++++ .../object/logic/math/CalculatorConfig.java | 144 ++++++++++++++++++ .../object/logic/math/MathOperationType.java | 68 +++++++++ .../textures/font/logic/calculator.png | Bin 0 -> 154 bytes .../textures/gui/slot_atlas.png | Bin 1892 -> 1992 bytes .../textures/item/calculator.png | Bin 0 -> 177 bytes .../textures/logic/calculator_addition.png | Bin 0 -> 173 bytes .../textures/logic/calculator_subtraction.png | Bin 0 -> 151 bytes 20 files changed, 548 insertions(+), 6 deletions(-) create mode 100644 src/generated/resources/assets/little_big_redstone/models/item/calculator.json create mode 100644 src/generated/resources/data/little_big_redstone/recipe/logic/calculator.json create mode 100644 src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/CalculatorLogicRenderer.java create mode 100644 src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/Calculator.java create mode 100644 src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/CalculatorConfig.java create mode 100644 src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/MathOperationType.java create mode 100644 src/main/resources/assets/little_big_redstone/textures/font/logic/calculator.png create mode 100644 src/main/resources/assets/little_big_redstone/textures/item/calculator.png create mode 100644 src/main/resources/assets/little_big_redstone/textures/logic/calculator_addition.png create mode 100644 src/main/resources/assets/little_big_redstone/textures/logic/calculator_subtraction.png diff --git a/src/generated/resources/assets/little_big_redstone/font/logic_component.json b/src/generated/resources/assets/little_big_redstone/font/logic_component.json index 056f0d2b..2e06fba9 100644 --- a/src/generated/resources/assets/little_big_redstone/font/logic_component.json +++ b/src/generated/resources/assets/little_big_redstone/font/logic_component.json @@ -6,7 +6,7 @@ "chars": [ "a" ], - "file": "little_big_redstone:font/logic/pulse_throttler.png", + "file": "little_big_redstone:font/logic/sequencer.png", "height": 7 }, { @@ -15,7 +15,7 @@ "chars": [ "b" ], - "file": "little_big_redstone:font/logic/selector.png", + "file": "little_big_redstone:font/logic/pulse_throttler.png", "height": 7 }, { @@ -24,7 +24,7 @@ "chars": [ "c" ], - "file": "little_big_redstone:font/logic/randomizer.png", + "file": "little_big_redstone:font/logic/selector.png", "height": 7 }, { @@ -33,7 +33,7 @@ "chars": [ "d" ], - "file": "little_big_redstone:font/logic/t_flip_flop.png", + "file": "little_big_redstone:font/logic/randomizer.png", "height": 7 }, { @@ -42,6 +42,15 @@ "chars": [ "e" ], + "file": "little_big_redstone:font/logic/t_flip_flop.png", + "height": 7 + }, + { + "type": "bitmap", + "ascent": 7, + "chars": [ + "f" + ], "file": "little_big_redstone:font/logic/rs_nor_latch.png", "height": 7 }, @@ -123,7 +132,7 @@ "chars": [ "8" ], - "file": "little_big_redstone:font/logic/reader.png", + "file": "little_big_redstone:font/logic/calculator.png", "height": 7 }, { @@ -132,7 +141,7 @@ "chars": [ "9" ], - "file": "little_big_redstone:font/logic/sequencer.png", + "file": "little_big_redstone:font/logic/reader.png", "height": 7 } ] diff --git a/src/generated/resources/assets/little_big_redstone/lang/en_us.json b/src/generated/resources/assets/little_big_redstone/lang/en_us.json index 7a58c0c2..16c0934a 100644 --- a/src/generated/resources/assets/little_big_redstone/lang/en_us.json +++ b/src/generated/resources/assets/little_big_redstone/lang/en_us.json @@ -25,6 +25,7 @@ "item.little_big_redstone.brown_floppy_disk": "Brown Floppy Disk", "item.little_big_redstone.brown_logic_array": "Brown Logic Array", "item.little_big_redstone.brown_sticky_note": "Brown Sticky Note", + "item.little_big_redstone.calculator": "Calculator", "item.little_big_redstone.cyan_floppy_disk": "Cyan Floppy Disk", "item.little_big_redstone.cyan_logic_array": "Cyan Logic Array", "item.little_big_redstone.cyan_sticky_note": "Cyan Sticky Note", @@ -133,6 +134,8 @@ "text.little_big_redstone.logic_config_button_label_sequencer_reset_port": "Reset Port", "text.little_big_redstone.logic_config_button_label_ticks_and_seconds": "%s ticks (%ss)", "text.little_big_redstone.logic_config_button_label_ticks_and_seconds_singular": "%s tick (%ss)", + "text.little_big_redstone.logic_config_button_tooltip_calculator_addition": "The output will be the sum of all of the inputs.", + "text.little_big_redstone.logic_config_button_tooltip_calculator_subtraction": "The output will be the difference of all of the inputs.", "text.little_big_redstone.logic_config_button_tooltip_duration": "The time for the output to be on.", "text.little_big_redstone.logic_config_button_tooltip_inputs": "The number of inputs that this component can accept.", "text.little_big_redstone.logic_config_button_tooltip_io_direction": "The direction this port should interact with redstone power on.", @@ -159,6 +162,8 @@ "text.little_big_redstone.logic_config_button_tooltip_sequencer_mode_strong": "While input is ON, the sequencer will increment until it has met X ticks and then emit an output of ON. While input is OFF, the sequencer will decrement.", "text.little_big_redstone.logic_config_button_tooltip_sequencer_mode_weak": "After an ON input signal, the sequencer will wait X ticks and then emit an output of ON.", "text.little_big_redstone.logic_config_button_tooltip_sequencer_reset_port": "Whether a second wire port should be added that will forcefully reset the sequencer's progress.", + "text.little_big_redstone.logic_config_math_operation_addition": "Addition", + "text.little_big_redstone.logic_config_math_operation_subtraction": "Subtraction", "text.little_big_redstone.logic_config_selector_mode_counter": "Counter", "text.little_big_redstone.logic_config_selector_mode_setter": "Setter", "text.little_big_redstone.logic_config_sequencer_mode_counter": "Counter", @@ -171,6 +176,7 @@ "text.little_big_redstone.logic_config_tooltip_duration": " Duration: %d", "text.little_big_redstone.logic_config_tooltip_inputs": " Inputs: %s", "text.little_big_redstone.logic_config_tooltip_io_signal": " Signal: %s", + "text.little_big_redstone.logic_config_tooltip_math_operation": " Operation: %s", "text.little_big_redstone.logic_config_tooltip_mode": " Mode: %s", "text.little_big_redstone.logic_config_tooltip_outputs": " Outputs: %s", "text.little_big_redstone.logic_config_tooltip_reader_fill": " Fill: %s", diff --git a/src/generated/resources/assets/little_big_redstone/models/item/calculator.json b/src/generated/resources/assets/little_big_redstone/models/item/calculator.json new file mode 100644 index 00000000..73ac2fdb --- /dev/null +++ b/src/generated/resources/assets/little_big_redstone/models/item/calculator.json @@ -0,0 +1,81 @@ +{ + "parent": "minecraft:item/generated", + "board_textures": { + "addition": "little_big_redstone:logic/calculator_addition", + "background": "little_big_redstone:logic/background_square", + "border": "little_big_redstone:logic/border_square", + "subtraction": "little_big_redstone:logic/calculator_subtraction" + }, + "color_palette": { + "black": { + "background": "ff000000", + "foreground": "ff726d81" + }, + "blue": { + "background": "ff000000", + "foreground": "ff4ba6f1" + }, + "brown": { + "background": "ff000000", + "foreground": "ffc66a1a" + }, + "cyan": { + "background": "ff000000", + "foreground": "ff47d5af" + }, + "gray": { + "background": "ff000000", + "foreground": "ffa8abbf" + }, + "green": { + "background": "ff000000", + "foreground": "ff18af2f" + }, + "light_blue": { + "background": "ff000000", + "foreground": "ff6ae4ff" + }, + "light_gray": { + "background": "ff000000", + "foreground": "ffc5d2e0" + }, + "lime": { + "background": "ff000000", + "foreground": "ffa4eb00" + }, + "magenta": { + "background": "ff000000", + "foreground": "ffff80f7" + }, + "orange": { + "background": "ff000000", + "foreground": "ffff920f" + }, + "pink": { + "background": "ff000000", + "foreground": "ffffb8ea" + }, + "purple": { + "background": "ff000000", + "foreground": "ffd857ff" + }, + "red": { + "background": "ff000000", + "foreground": "ffff0000" + }, + "white": { + "background": "ff000000", + "foreground": "ffeff5ff" + }, + "yellow": { + "background": "ff000000", + "foreground": "ffffe800" + } + }, + "item_textures": { + "background": "little_big_redstone:item/logic_background_square", + "border": "little_big_redstone:item/logic_border_square", + "icon": "little_big_redstone:item/calculator" + }, + "loader": "little_big_redstone:logic" +} \ No newline at end of file diff --git a/src/generated/resources/data/little_big_redstone/recipe/logic/calculator.json b/src/generated/resources/data/little_big_redstone/recipe/logic/calculator.json new file mode 100644 index 00000000..5e3a1286 --- /dev/null +++ b/src/generated/resources/data/little_big_redstone/recipe/logic/calculator.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "G": { + "tag": "c:ingots/gold" + }, + "Q": { + "tag": "c:gems/quartz" + }, + "R": { + "tag": "c:dusts/redstone" + }, + "r": { + "item": "little_big_redstone:redstone_bit" + } + }, + "pattern": [ + "GG ", + "QrR", + "GG " + ], + "result": { + "count": 1, + "id": "little_big_redstone:calculator" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/little_big_redstone/tags/item/logic_components.json b/src/generated/resources/data/little_big_redstone/tags/item/logic_components.json index 62c12808..0f67bae0 100644 --- a/src/generated/resources/data/little_big_redstone/tags/item/logic_components.json +++ b/src/generated/resources/data/little_big_redstone/tags/item/logic_components.json @@ -1,6 +1,7 @@ { "values": [ "little_big_redstone:and_gate", + "little_big_redstone:calculator", "little_big_redstone:debugger", "little_big_redstone:io", "little_big_redstone:nand_gate", diff --git a/src/main/java/net/swedz/little_big_redstone/LBRText.java b/src/main/java/net/swedz/little_big_redstone/LBRText.java index cb51febd..4f557eca 100644 --- a/src/main/java/net/swedz/little_big_redstone/LBRText.java +++ b/src/main/java/net/swedz/little_big_redstone/LBRText.java @@ -65,6 +65,8 @@ public enum LBRText implements TranslatableTextEnum LOGIC_CONFIG_BUTTON_TOOLTIP_IO_SIGNAL_COMPARISON_MODE_GREATER_THAN_OR_EQUAL_TO("The input signal must be greater than or equal to %s."), LOGIC_CONFIG_BUTTON_TOOLTIP_IO_SIGNAL_COMPARISON_MODE_LESS_THAN_OR_EQUAL_TO("The input signal must be less than or equal to %s."), LOGIC_CONFIG_BUTTON_TOOLTIP_IO_SIGNAL_COMPARISON_OUTPUT("The output signal will be equal to %s."), + LOGIC_CONFIG_BUTTON_TOOLTIP_CALCULATOR_ADDITION("The output will be the sum of all of the inputs."), + LOGIC_CONFIG_BUTTON_TOOLTIP_CALCULATOR_SUBTRACTION("The output will be the difference of all of the inputs."), LOGIC_CONFIG_BUTTON_TOOLTIP_IO_SIGNAL_STRENGTH_INPUT("The redstone signal strength required for the output to be on."), LOGIC_CONFIG_BUTTON_TOOLTIP_IO_SIGNAL_STRENGTH_OUTPUT("The redstone signal strength that will be outputted."), LOGIC_CONFIG_BUTTON_TOOLTIP_OUTPUTS("The number of outputs that this component can yield."), @@ -94,6 +96,9 @@ public enum LBRText implements TranslatableTextEnum LOGIC_CONFIG_TOOLTIP_DIRECTION(" Direction: %s"), LOGIC_CONFIG_TOOLTIP_DURATION(" Duration: %d"), LOGIC_CONFIG_TOOLTIP_INPUTS(" Inputs: %s"), + LOGIC_CONFIG_TOOLTIP_MATH_OPERATION(" Operation: %s"), + LOGIC_CONFIG_MATH_OPERATION_ADDITION("Addition"), + LOGIC_CONFIG_MATH_OPERATION_SUBTRACTION("Subtraction"), LOGIC_CONFIG_TOOLTIP_IO_SIGNAL(" Signal: %s"), LOGIC_CONFIG_TOOLTIP_MODE(" Mode: %s"), LOGIC_CONFIG_TOOLTIP_OUTPUTS(" Outputs: %s"), diff --git a/src/main/java/net/swedz/little_big_redstone/LBRTooltips.java b/src/main/java/net/swedz/little_big_redstone/LBRTooltips.java index 3f3e79da..dc9801b6 100644 --- a/src/main/java/net/swedz/little_big_redstone/LBRTooltips.java +++ b/src/main/java/net/swedz/little_big_redstone/LBRTooltips.java @@ -5,6 +5,7 @@ import net.minecraft.network.chat.Style; import net.minecraft.network.chat.TextColor; import net.swedz.little_big_redstone.microchip.object.logic.config.LogicComparisonMode; +import net.swedz.little_big_redstone.microchip.object.logic.math.MathOperationType; import net.swedz.little_big_redstone.microchip.object.logic.reader.LogicReaderMode; import net.swedz.little_big_redstone.microchip.object.logic.selector.LogicSelectorMode; import net.swedz.little_big_redstone.microchip.object.logic.sequencer.LogicSequencerMode; @@ -50,6 +51,12 @@ public static Style directionStyle(Direction direction) case EAST -> LBRText.DIRECTION_EAST; }).text().withStyle(directionStyle(direction)); + public static final Parser MATH_OPERATION_PARSER = (type) -> (switch (type) + { + case ADDITION -> LBRText.LOGIC_CONFIG_MATH_OPERATION_ADDITION; + case SUBTRACTION -> LBRText.LOGIC_CONFIG_MATH_OPERATION_SUBTRACTION; + }).text().withStyle(HIGHLIGHT_STYLE); + public static final Parser BOOLEAN_YES_NO_PARSER = (value) -> value ? LBRText.YES.text().withStyle(YES_STYLE) : LBRText.NO.text().withStyle(NO_STYLE); public static final Parser READER_MODE_PARSER = (value) -> (switch (value) diff --git a/src/main/java/net/swedz/little_big_redstone/datagen/client/provider/models/LogicItemModelsDatagenProvider.java b/src/main/java/net/swedz/little_big_redstone/datagen/client/provider/models/LogicItemModelsDatagenProvider.java index 7d1f9c15..250c1bff 100644 --- a/src/main/java/net/swedz/little_big_redstone/datagen/client/provider/models/LogicItemModelsDatagenProvider.java +++ b/src/main/java/net/swedz/little_big_redstone/datagen/client/provider/models/LogicItemModelsDatagenProvider.java @@ -11,6 +11,7 @@ import net.swedz.little_big_redstone.client.model.logic.LogicBakingModelData; import net.swedz.little_big_redstone.microchip.object.logic.LogicType; import net.swedz.little_big_redstone.microchip.object.logic.LogicTypes; +import net.swedz.little_big_redstone.microchip.object.logic.math.MathOperationType; import java.util.Locale; import java.util.Set; @@ -40,6 +41,14 @@ private void registerLogicModels() this.logicComponent(LogicTypes.NOR, BackgroundType.SQUARE, true); this.logicComponent(LogicTypes.XOR, BackgroundType.SQUARE, true); + this.logicComponent(LogicTypes.CALCULATOR, BackgroundType.SQUARE, false, (b) -> + { + for(var type : MathOperationType.values()) + { + b.boardTexture(type.textureName(), LBR.id("logic/calculator_%s".formatted(type.textureName()))); + } + }); + this.logicComponent(LogicTypes.READER, BackgroundType.CIRCLE, true); this.logicComponent(LogicTypes.SEQUENCER, BackgroundType.SQUARE, false, (b) -> b diff --git a/src/main/java/net/swedz/little_big_redstone/datagen/server/provider/recipes/LogicRecipesDatagenProvider.java b/src/main/java/net/swedz/little_big_redstone/datagen/server/provider/recipes/LogicRecipesDatagenProvider.java index 20e43599..eac5c545 100644 --- a/src/main/java/net/swedz/little_big_redstone/datagen/server/provider/recipes/LogicRecipesDatagenProvider.java +++ b/src/main/java/net/swedz/little_big_redstone/datagen/server/provider/recipes/LogicRecipesDatagenProvider.java @@ -96,6 +96,11 @@ protected void buildRecipes(RecipeOutput output, HolderLookup.Provider registrie .define('1', LBRItems.valueOf("and_gate")) .define('2', LBRItems.valueOf("nor_gate"))); + logicComponent(output, LogicTypes.CALCULATOR, (b) -> b + .pattern("GG ") + .pattern("QrR") + .pattern("GG ")); + logicComponent(output, LogicTypes.READER, (b) -> b .pattern("R ") .pattern("QrR") diff --git a/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/LogicRenderers.java b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/LogicRenderers.java index aa2ebd20..7240de7e 100644 --- a/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/LogicRenderers.java +++ b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/LogicRenderers.java @@ -2,7 +2,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; +import net.swedz.little_big_redstone.LBR; import net.swedz.little_big_redstone.gui.microchip.logic.renderer.IORenderer; +import net.swedz.little_big_redstone.gui.microchip.logic.renderer.CalculatorLogicRenderer; import net.swedz.little_big_redstone.gui.microchip.logic.renderer.OnOffLogicRenderer; import net.swedz.little_big_redstone.gui.microchip.logic.renderer.SequencerRenderer; import net.swedz.little_big_redstone.gui.microchip.logic.renderer.SimpleLogicRenderer; @@ -32,6 +34,8 @@ public final class LogicRenderers register(LogicTypes.NOR, SimpleLogicRenderer::new); register(LogicTypes.XOR, SimpleLogicRenderer::new); + register(LogicTypes.CALCULATOR, CalculatorLogicRenderer::new); + register(LogicTypes.READER, SimpleLogicRenderer::new); register(LogicTypes.SEQUENCER, SequencerRenderer::new); @@ -46,6 +50,24 @@ public final class LogicRenderers public static void init() { RENDERERS = createRenderers(); + assertAllTypesAreRegistered(); + } + + private static void assertAllTypesAreRegistered() + { + boolean missing = false; + for(var type : LogicTypes.values()) + { + if(!RENDERERS.containsKey(type)) + { + missing = true; + LBR.LOGGER.error("Did not register renderer for logic type {}, did you forget?", type.id()); + } + } + if(missing) + { + throw new IllegalStateException("Missing renderers for some logic types"); + } } private static void register(LogicType type, LogicRendererProvider provider) diff --git a/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/CalculatorLogicRenderer.java b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/CalculatorLogicRenderer.java new file mode 100644 index 00000000..6fdfdfd5 --- /dev/null +++ b/src/main/java/net/swedz/little_big_redstone/gui/microchip/logic/renderer/CalculatorLogicRenderer.java @@ -0,0 +1,34 @@ +package net.swedz.little_big_redstone.gui.microchip.logic.renderer; + +import net.swedz.little_big_redstone.LBR; +import net.swedz.little_big_redstone.LBRClientShaders; +import net.swedz.little_big_redstone.gui.microchip.logic.LogicRenderer; +import net.swedz.little_big_redstone.microchip.object.logic.math.Calculator; +import net.swedz.tesseract.neoforge.helper.guigraphics.TesseractGuiGraphics; + +public final class CalculatorLogicRenderer extends LogicRenderer +{ + @Override + public void render(Context context, TesseractGuiGraphics graphics, Calculator component, int x, int y) + { + var size = component.size(); + + this.renderAllPorts(context, graphics, x, y, component, 1, 1, 1); + this.renderBackground(context, graphics, x, y, component); + + graphics.setColor(context.foregroundColor()); + graphics.setTextureShader( + LBRClientShaders::logicScanline, + (shader) -> shader.getUniform("LogicUV").set(16f, 16f) + ); + graphics.setTextures( + context.getTexture(component.config().operation.textureName()), + LBR.id("textures/logic/scanline.png") + ); + int centerX = x + size.centerX() - 8; + int centerY = y + size.centerY() - 8; + graphics.blit(centerX, centerY, 0, 0, 16, 16, 16, 16); + graphics.resetTextureShader(); + graphics.resetColor(); + } +} diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicTypes.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicTypes.java index 470d8221..03df0433 100644 --- a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicTypes.java +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/LogicTypes.java @@ -19,6 +19,7 @@ import net.swedz.little_big_redstone.microchip.object.logic.io.LogicIO; import net.swedz.little_big_redstone.microchip.object.logic.latch.rs.RSNORLatch; import net.swedz.little_big_redstone.microchip.object.logic.latch.tflipflop.TFlipFlop; +import net.swedz.little_big_redstone.microchip.object.logic.math.Calculator; import net.swedz.little_big_redstone.microchip.object.logic.pulse.PulseThrottler; import net.swedz.little_big_redstone.microchip.object.logic.randomizer.LogicRandomizer; import net.swedz.little_big_redstone.microchip.object.logic.reader.LogicReader; @@ -56,6 +57,8 @@ public final class LogicTypes public static final LogicType NOR = registerGate("nor", "NOR", NORGate.CODEC, NORGate.STREAM_CODEC, NORGate::new); public static final LogicType XOR = registerGate("xor", "XOR", XORGate.CODEC, XORGate.STREAM_CODEC, XORGate::new); + public static final LogicType CALCULATOR = register("calculator", "Calculator", Calculator.CODEC, Calculator.STREAM_CODEC, Calculator::new); + public static final LogicType READER = register("reader", "Reader", LogicReader.CODEC, LogicReader.STREAM_CODEC, LogicReader::new); public static final LogicType SEQUENCER = register("sequencer", "Sequencer", LogicSequencer.CODEC, LogicSequencer.STREAM_CODEC, LogicSequencer::new); diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/Calculator.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/Calculator.java new file mode 100644 index 00000000..089d5c29 --- /dev/null +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/Calculator.java @@ -0,0 +1,121 @@ +package net.swedz.little_big_redstone.microchip.object.logic.math; + +import com.google.common.base.Objects; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.Mth; +import net.minecraft.world.item.DyeColor; +import net.swedz.little_big_redstone.microchip.object.logic.LogicComponent; +import net.swedz.little_big_redstone.microchip.object.logic.LogicContext; +import net.swedz.little_big_redstone.microchip.object.logic.LogicGridSize; +import net.swedz.little_big_redstone.microchip.object.logic.LogicType; +import net.swedz.little_big_redstone.microchip.object.logic.LogicTypes; + +import java.util.Optional; + +public final class Calculator extends LogicComponent +{ + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> instance + .group( + CalculatorConfig.CODEC.fieldOf("config").forGetter(LogicComponent::config), + DyeColor.CODEC.optionalFieldOf("color").forGetter(LogicComponent::color), + Codec.INT.optionalFieldOf("output", 0).forGetter(Calculator::output) + ) + .apply(instance, Calculator::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + CalculatorConfig.STREAM_CODEC, LogicComponent::config, + ByteBufCodecs.optional(DyeColor.STREAM_CODEC), Calculator::color, + ByteBufCodecs.VAR_INT, Calculator::output, + Calculator::new + ); + + private int outputState; + + private Calculator(CalculatorConfig config, Optional color, int outputState) + { + super(config, color); + this.outputState = outputState; + } + + private Calculator(Optional color, int outputState) + { + super(color); + this.outputState = outputState; + } + + public Calculator() + { + this(Optional.empty(), 0); + } + + @Override + protected CalculatorConfig defaultConfig() + { + return new CalculatorConfig(); + } + + @Override + public LogicType type() + { + return LogicTypes.CALCULATOR; + } + + @Override + protected void processTickInternal(LogicContext context, int[] inputs) + { + int originalOutputState = outputState; + outputState = Mth.clamp(config.operation.execute(inputs), 0, 15); + if(outputState != originalOutputState) + { + context.markDirty(this); + } + } + + @Override + protected int outputInternal(int index) + { + return outputState; + } + + public int output() + { + return this.output(0); + } + + @Override + public LogicGridSize size() + { + int inputs = this.inputs(); + return new LogicGridSize(1, Math.max(1, inputs / 2)); + } + + @Override + protected void internalLoadFrom(Calculator other) + { + outputState = other.outputInternal(0); + } + + @Override + public void internalResetForPickup() + { + outputState = 0; + } + + @Override + public int hashCode() + { + return Objects.hashCode(this.type(), config, color); + } + + @Override + public boolean equals(Object o) + { + return this == o || + (o instanceof Calculator other && Objects.equal(config, other.config) && Objects.equal(color, other.color)); + } +} diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/CalculatorConfig.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/CalculatorConfig.java new file mode 100644 index 00000000..cf411cb7 --- /dev/null +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/CalculatorConfig.java @@ -0,0 +1,144 @@ +package net.swedz.little_big_redstone.microchip.object.logic.math; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.swedz.little_big_redstone.LBR; +import net.swedz.little_big_redstone.LBRText; +import net.swedz.little_big_redstone.LBRTooltips; +import net.swedz.little_big_redstone.microchip.object.logic.config.LogicConfig; +import net.swedz.little_big_redstone.microchip.object.logic.config.LogicConfigButtonReference; +import net.swedz.little_big_redstone.microchip.object.logic.config.LogicConfigMenuBuilder; +import net.swedz.tesseract.neoforge.api.range.IntRange; +import net.swedz.tesseract.neoforge.helper.CodecHelper; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +import static net.swedz.little_big_redstone.LBRTextLine.*; + +public final class CalculatorConfig extends LogicConfig +{ + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance + .group( + Codec.INT.optionalFieldOf("input_count", 2).forGetter((config) -> config.inputs), + CodecHelper.forLowercaseEnum(MathOperationType.class).optionalFieldOf("operation", MathOperationType.ADDITION).forGetter((config) -> config.operation) + ) + .apply(instance, CalculatorConfig::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, (config) -> config.inputs, + CodecHelper.forEnumStream(MathOperationType.class), (config) -> config.operation, + CalculatorConfig::new + ); + + public int inputs; + + public MathOperationType operation; + + private CalculatorConfig(int inputs, MathOperationType operation) + { + this.inputs = inputs; + this.operation = operation; + } + + public CalculatorConfig() + { + this.inputs = this.inputsAllowed().min(); + this.operation = MathOperationType.ADDITION; + } + + @Override + public IntRange inputsAllowed() + { + return new IntRange(2, 10); + } + + @Override + public int inputs() + { + return inputs; + } + + @Override + public IntRange outputsAllowed() + { + return new IntRange(1, 1); + } + + @Override + public int outputs() + { + return 1; + } + + @Override + public void appendHoverText(List lines) + { + lines.add(line(LBRText.LOGIC_CONFIG_TOOLTIP_INPUTS).arg(inputs)); + lines.add(line(LBRText.LOGIC_CONFIG_TOOLTIP_MATH_OPERATION).arg(operation, LBRTooltips.MATH_OPERATION_PARSER)); + } + + @Override + public boolean hasMenu() + { + return true; + } + + private LBRText operationTooltip() + { + return switch (operation) + { + case ADDITION -> LBRText.LOGIC_CONFIG_BUTTON_TOOLTIP_CALCULATOR_ADDITION; + case SUBTRACTION -> LBRText.LOGIC_CONFIG_BUTTON_TOOLTIP_CALCULATOR_SUBTRACTION; + }; + } + + @Override + public void buildMenu(LogicConfigMenuBuilder builder, int width, int height) + { + var operationButton = new AtomicReference>(); + + builder.addSlider(LBRText.LOGIC_CONFIG_BUTTON_LABEL_INPUTS.text(), Component.empty(), LBRText.LOGIC_CONFIG_BUTTON_TOOLTIP_INPUTS.text(), 0, 0, width - 18 - 4, 18, this.inputsAllowed().min(), this.inputsAllowed().max(), inputs, 1, 0, (value) -> inputs = value.intValue()); + + operationButton.set(builder.addCycleButton(this.operationTooltip().text(), width - 18, 0, LBR.id("textures/gui/slot_atlas.png"), operation, Arrays.asList(MathOperationType.values()), (value) -> + { + operation = value; + var button = operationButton.get(); + if(button != null) + { + button.setTooltip(this.operationTooltip().text()); + } + })); + } + + @Override + protected void internalLoadFrom(CalculatorConfig other) + { + inputs = this.inputsAllowed().clamp(other.inputs); + operation = other.operation; + } + + @Override + public void resetForPickup() + { + } + + @Override + public int hashCode() + { + return Objects.hash(inputs, operation); + } + + @Override + public boolean equals(Object o) + { + return this == o || + (o instanceof CalculatorConfig other && inputs == other.inputs && operation == other.operation); + } +} diff --git a/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/MathOperationType.java b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/MathOperationType.java new file mode 100644 index 00000000..4de261af --- /dev/null +++ b/src/main/java/net/swedz/little_big_redstone/microchip/object/logic/math/MathOperationType.java @@ -0,0 +1,68 @@ +package net.swedz.little_big_redstone.microchip.object.logic.math; + +import net.swedz.little_big_redstone.gui.logicconfig.button.iconcycle.IconCycleLogicConfigButtonIcon; + +import java.util.function.Function; + +public enum MathOperationType implements IconCycleLogicConfigButtonIcon +{ + ADDITION(7 * 18, 0, (inputs) -> + { + int sum = 0; + for(int input : inputs) + { + sum += input; + } + return sum; + }), + SUBTRACTION(8 * 18, 0, (inputs) -> + { + int difference = 0; + for(int index = 0; index < inputs.length; index++) + { + int input = inputs[index]; + if(index == 0) + { + difference = input; + } + else + { + difference -= input; + } + } + return difference; + }); + + private final int u, v; + + private final Function operation; + + MathOperationType(int u, int v, Function operation) + { + this.u = u; + this.v = v; + this.operation = operation; + } + + public String textureName() + { + return this.name().toLowerCase(); + } + + @Override + public int u() + { + return u; + } + + @Override + public int v() + { + return v; + } + + public int execute(int[] inputs) + { + return operation.apply(inputs); + } +} diff --git a/src/main/resources/assets/little_big_redstone/textures/font/logic/calculator.png b/src/main/resources/assets/little_big_redstone/textures/font/logic/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1dd51bb6e708d758523dea068ea674bcef8641 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJx0U~c5>$3n-jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DXP~X$VF+?If`42w}PXvSTlw%AEvH@yZ3@;l_ tHe^`LE|FE>bmNfrIea6cl);dhnc

=0T>2&i}&Fl-Ygp2df>0We*N?1<>x;F08jMC$A8;>ybrzMhyCmpfa|co z5B36HDIkle5Tg^t?OK?cX;df z)oXg!6YLBD7=I5`Yw&uMb#up3t#w-?uylCqbB48spDt$zKx??R4%j2Lu4l{8tsUOh zxl7iUk7NAtOg%njeE!tI0i5MafZ;|S-^_d8NUi-_*Ex3Yy6eZ63@@y5mH-q-2tjMV zp1~g*KS%xhHN)TfGiW_FrF;zIk7erdDdY2}4i4aK0e>jg+(g4L^c+j9xsLk$vR}RL z(&rnD*SGe78)pqbQEv7%L$lT+_N>=FdiaZ}J>Zu!1Yo#%dyYB7K=d4QT6?#SIpe*0 z_8zPEX|1mx>$xVvoc$HR*_8oZGyJuC>(@T_ux{&had2k{K)Dg;j%R7@-8ya6x4`dr4Zx>QpFV!O z&W|5IhBvDM@H)JGKYqOx0C<{RzXx#r%s;$+KMX%S->w0;c?IzCWxxW%`Q><)J@%Z^ zdmTr)UJhpWzXd3t`G>a)9OZ_7#&z`UaqspIu!9p3tV^_t%G1Uo|j z#sk$FydGuU+_6+^-PQ;!9p3t!VXfh(%NYXD8m_Ga_DHSk*)nu%hqra^lJ(`|7=Jud zkAF`YpFeeQ0B89UV7QUTH}l>%QfvR#b&lP;?)vd1!wajNB>=?{LeSc;XYj|y&r$z= z&G5JW3|fy(DIdf5W0`t<%J}@Lg9A8Q0E#s?(J%}>#}aF$Q&_{$gqm_~i@%7=Lcwo@3515Ix77*50jS&Umk$y~pZ(TI=h_ zdaj8uXMY87c4a`<41ew3`nAtJtlN5B9NZZKP;SJz<5^mJw~k&*&K>LBYw0x+!Ycp> z<|hI{uw8#55U{UZeveH(0FM`B0swdPzkj#eeY_66;fMX~7J&1x zzYhJz;U8W_jK{s~vF9bd*YPOV%Y)hV6~GvQ6~q51Pw0DGN6#MDKL6R*$ARtp7U0#w z;je~aSl{y)cKZ4A=gZsw&%c%LFmN!t{zjnRr_*`w=a-jL z`{&^n_hjYXCmH z0(g5Hu)uKsc-+e#dtTCe9glLoJeb}87GV6&Kin?xC{O5nTu09y*FOK**T;eF{uW?- z+28*8ifR~!H9c<~#lyhP8&DE=LGJHC$TEjKi>#IHBgQEsuG(Oqa49!}%*t1=G>){_= z+5_GlAppaZx96BM3`EZ{r`o$Z=1lkM*?X$pr&{0M*K60C z{K1Y8fZ++;bKFa{cXjkya_&^`UQ4fu5Px0)Krp`%2!ieU8-aj*?fM&mfPMKH00a|& zW9$7l2fgPJMgSgP&+uORyus(9BLrX^fVpE%wWd1eRBNi^7UmwO{kcnZZhN1f(eQy+ z0FSG8crQi3@H6WO0T`aVJ;$7CO?Awv)>Ow9ONX~TXIN|a>GGcdeEat8e6)J+<9}w> z4sUg?;pZxE0q$@59lGT^H+SV90^Q%GA>TUum!jgo3m5rYfRD$VYE5-qQVo53{?_3i z)>nJL2i^kgat*MSV({p;(OwGlky-x)Az$<`#jRU%7_*>W3 zZ+&e3U;?neEdx5N?OES@9$^Fkf(`kNKoIQo^5SPhkjh)LAqI{ClW+y(8Hn}t^e@od VtTWZP|9AiZ002ovPDHLkV1ig}BW{AjW&ghxo&UR!M!|JyR2D8K^Bp9|u$gr&P SUC#(Kk-^i|&t;ucLK6V>J29^S literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/little_big_redstone/textures/logic/calculator_addition.png b/src/main/resources/assets/little_big_redstone/textures/logic/calculator_addition.png new file mode 100644 index 0000000000000000000000000000000000000000..aedc5abaef202c735c1c2f173e266e5fc3be3923 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sEXgD|57Yp@DX(8<%qF~q_@`Op9V_ROjcoL-Z8Gx8Wt)K~nq z__5bPV1c{x#==t^OIN;UDq)!1a=U}C%~40dh~Y{3oPX?%jo+ASOS9^>bP0l+XkKIUOhq literal 0 HcmV?d00001