diff --git a/core/src/mindustry/content/SerpuloTechTree.java b/core/src/mindustry/content/SerpuloTechTree.java index b33d68d4f2..92a8e966d0 100644 --- a/core/src/mindustry/content/SerpuloTechTree.java +++ b/core/src/mindustry/content/SerpuloTechTree.java @@ -169,7 +169,6 @@ public class SerpuloTechTree{ }); }); - //logic disabled until further notice node(microProcessor, () -> { node(switchBlock, () -> { node(message, () -> { @@ -177,6 +176,10 @@ public class SerpuloTechTree{ node(largeLogicDisplay, () -> { }); + + node(logicDisplayTile, () -> { + + }); }); node(memoryCell, () -> { diff --git a/core/src/mindustry/world/blocks/logic/LogicDisplay.java b/core/src/mindustry/world/blocks/logic/LogicDisplay.java index bb30c3bbff..8ca5ac00f9 100644 --- a/core/src/mindustry/world/blocks/logic/LogicDisplay.java +++ b/core/src/mindustry/world/blocks/logic/LogicDisplay.java @@ -111,6 +111,8 @@ public class LogicDisplay extends Block{ //don't bother processing commands if displays are off if(!commands.isEmpty() && buffer != null){ Draw.draw(Draw.z(), () -> { + if(buffer == null) return; + Tmp.m1.set(Draw.proj()); Tmp.m2.set(Draw.trans()); Draw.proj(0, 0, buffer.getWidth(), buffer.getHeight()); diff --git a/core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java b/core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java index b511c8224a..f4b0883318 100644 --- a/core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java +++ b/core/src/mindustry/world/blocks/logic/TileableLogicDisplay.java @@ -18,6 +18,7 @@ import static mindustry.Vars.*; public class TileableLogicDisplay extends LogicDisplay{ protected static final Seq queue = new Seq<>(); protected static final Seq displays = new Seq<>(); + protected static final ObjectSet buffers = new ObjectSet<>(); protected static final IntSet processed = new IntSet(); //in tiles @@ -84,21 +85,52 @@ public class TileableLogicDisplay extends LogicDisplay{ } } + if(root.prevBuffers == null){ + root.prevBuffers = new Seq<>(); + } + + //add all new buffers + buffers.clear(); + for(var member : displays){ + if(member.buffer != null && buffers.add(member.buffer)){ + root.prevBuffers.add(new MergeBuffer(member.buffer, member.originX, member.originY, member.tilesWidth, member.tilesHeight)); + } + } + int tilesWidth = topX - botX + 1, tilesHeight = topY - botY + 1; //the new root display has been assigned for(var member : displays){ + member.needsUpdate = false; member.rootDisplay = root; member.tilesWidth = tilesWidth; member.tilesHeight = tilesHeight; member.originX = botX; member.originY = botY; + member.buffer = null; + } + } - //TODO: preserve buffers later - if(member.buffer != null){ - member.buffer.dispose(); - member.buffer = null; - } + static class MergeBuffer{ + FrameBuffer buffer; + int x, y, width, height; + + MergeBuffer(FrameBuffer buffer, int x, int y, int width, int height){ + this.buffer = buffer; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + @Override + public String toString(){ + return "MergeBuffer{" + + "x=" + x + + ", y=" + y + + ", width=" + width + + ", height=" + height + + '}'; } } @@ -107,8 +139,10 @@ public class TileableLogicDisplay extends LogicDisplay{ public TileableLogicDisplayBuild rootDisplay = this; //size of display area public int tilesWidth = 1, tilesHeight = 1, originX, originY; + public @Nullable Seq prevBuffers; public int bits = 0; + public boolean needsUpdate = false; @Override public void display(Table table){ @@ -135,6 +169,11 @@ public class TileableLogicDisplay extends LogicDisplay{ @Override public void draw(){ + if(needsUpdate){ + needsUpdate = false; + linkDisplays(this); + } + Draw.rect(backRegion, x, y); //don't even bother processing anything when displays are off. @@ -144,9 +183,33 @@ public class TileableLogicDisplay extends LogicDisplay{ Draw.draw(Draw.z(), () -> { if(buffer == null && tilesWidth <= maxDisplayDimensions && tilesHeight <= maxDisplayDimensions){ buffer = new FrameBuffer(32 * tilesWidth, 32 * tilesHeight); + + Tmp.m1.set(Draw.proj()); + Tmp.m2.set(Draw.trans()); + Draw.proj(0, 0, buffer.getWidth(), buffer.getHeight()); + //clear the buffer - some OSs leave garbage in it buffer.begin(Pal.darkerMetal); + if(prevBuffers != null){ + for(var other : prevBuffers){ + Draw.rect(Draw.wrap(other.buffer.getTexture()), (other.x - originX) * 32 + other.buffer.getWidth()/2f, (other.y - originY) * 32 + other.buffer.getHeight()/2f, other.buffer.getWidth(), -other.buffer.getHeight()); + Draw.flush(); + } + } + buffer.end(); + Draw.proj(Tmp.m1); + Draw.trans(Tmp.m2); + Draw.reset(); + } + + if(prevBuffers != null){ + for(var other : prevBuffers){ + if(!other.buffer.isDisposed()){ + other.buffer.dispose(); + } + } + prevBuffers.clear(); } }); @@ -195,7 +258,7 @@ public class TileableLogicDisplay extends LogicDisplay{ public void onProximityAdded(){ super.onProximityAdded(); - linkDisplays(this); + needsUpdate = true; updateOthers(); } @@ -208,7 +271,7 @@ public class TileableLogicDisplay extends LogicDisplay{ for(var other : proximity){ if(other instanceof TileableLogicDisplayBuild tl && !processed.contains(tl.id)){ - linkDisplays(tl); + tl.needsUpdate = true; } }