From 92c86a571985cb2d4272b07ae816d55a4011ae73 Mon Sep 17 00:00:00 2001 From: DaSH Date: Tue, 28 Apr 2026 02:17:43 +0200 Subject: [PATCH] Hexadecimal Display, Negative Number Display Fix, Active Digit Selection --- .../render/tileentity/RenderRBMKNumitron.java | 104 +++++++++++++++--- .../machine/rbmk/TileEntityRBMKNumitron.java | 37 +++++++ src/main/java/com/hbm/util/BobMathUtil.java | 56 +++++----- .../models/network/numitron_lights.png | Bin 712 -> 487 bytes 4 files changed, 157 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/hbm/render/tileentity/RenderRBMKNumitron.java b/src/main/java/com/hbm/render/tileentity/RenderRBMKNumitron.java index 83c4202ef..ec1e3cfd6 100644 --- a/src/main/java/com/hbm/render/tileentity/RenderRBMKNumitron.java +++ b/src/main/java/com/hbm/render/tileentity/RenderRBMKNumitron.java @@ -54,35 +54,109 @@ public class RenderRBMKNumitron extends TileEntitySpecialRenderer { double w = 8D / scale; double h = 13D / scale; double yOffset = 0.5625D; + double line_height = 0.25D; - String value = BobMathUtil.getShortNumber(unit.value); - String fill_char = unit.no_leading_zeroes?" ":"0"; - while(value.length() < 7) value = fill_char + value; + String value = ""; + switch((int)unit.display_mode) { + case 0: // Normal + value = BobMathUtil.getShortNumber(unit.value); + break; + case 1: // Integer display + // Overflow handling + if (unit.value > 9999999) { + value = "9999999"; + break; + } + // Underflow handling + if (unit.value < -999999) { + value = "-999999"; + break; + } + value = Long.toString(unit.value); + break; + case 2: // Signed Hexadecimal display + // Overflow handling + if (unit.value > 0x7FFFFFF) { + value = "7ffffff"; + break; + } + // Underflow handling + // Theoretically this value is equal to 0x8000000 in a 28bit signed integer, but it's a long so we have to adapt + if (unit.value < -134217728) { + value = "8000000"; + break; + } + value = Long.toHexString(unit.value); + long length = value.length(); + + // A negative number will have many leading F's, so this needs to be accounted for + if(length > 7) { + value = value.substring((int)length-7); + } + break; + case 3: // Unsigned Hexadecimal display + // Overflow handling + if (unit.value > 0xFFFFFFF) { + value = "fffffff"; + break; + } + // Underflow handling + if (unit.value < 0) { + value = "-0"; + break; + } + value = Long.toHexString(unit.value); + break; + default: + value = BobMathUtil.getShortNumber(unit.value); + break; + } + + //** Fill up to 7 characters */ + if ((value.length() < 7) && (value.charAt(0) == '-') && (unit.no_leading_zeroes == false)) { + value = value.substring(1); + while(value.length() < 6) value = "0" + value; + value = "-" + value; + } else { + String fill_char = unit.no_leading_zeroes?" ":"0"; + while(value.length() < 7) value = fill_char + value; + } Tessellator tess = Tessellator.instance; tess.startDrawingQuads(); for(int j = 0; j < 7; j++) { + + //** Check if this digit is active */ + //** 0x40 is the bit for the left-most digit, with which this starts */ + if((unit.active_digits & (0x40L>>j)) == 0) continue; + double zOffset = (j - 3) * 0.1D; char c = value.charAt(j); double u = -1; double v = 0; if(c == ' ') continue; - if(c == '.') {u = 0.9; v = 0.5;} - if(c == '-') {u = 0.8; v = 0.5;} - else if(c == 'k') {u = 0.0; v = 0.5;} - else if(c == 'M') {u = 0.1; v = 0.5;} - else if(c == 'G') {u = 0.2; v = 0.5;} - else if(c == 'T') {u = 0.3; v = 0.5;} - else if(c == 'P') {u = 0.4; v = 0.5;} - else if(c == 'E') {u = 0.5; v = 0.5;} // i would love to say this sucks, but this is actually surprisingly easy to read and probably the most performant way of doing it - int charVal = c - '0'; // no string operations, no int parsing, no nothing, we just rawdog shit shit + if(c == '.') {u = 0.9; v = 1*line_height;} + if(c == '-') {u = 0.8; v = 1*line_height;} + else if(c == 'k') {u = 0.0; v = 1*line_height;} + else if(c == 'M') {u = 0.1; v = 1*line_height;} + else if(c == 'G') {u = 0.2; v = 1*line_height;} + else if(c == 'T') {u = 0.3; v = 1*line_height;} + else if(c == 'P') {u = 0.4; v = 1*line_height;} + else if(c == 'E') {u = 0.5; v = 1*line_height;} + else if(c == 'a') {u = 0.0; v = 2*line_height;} + else if(c == 'b') {u = 0.1; v = 2*line_height;} + else if(c == 'c') {u = 0.2; v = 2*line_height;} + else if(c == 'd') {u = 0.3; v = 2*line_height;} + else if(c == 'e') {u = 0.4; v = 2*line_height;} + else if(c == 'f') {u = 0.5; v = 2*line_height;} // i would love to say this sucks, but this is actually surprisingly easy to read and probably the most performant way of doing it + int charVal = c - '0'; // no string operations, no int parsing, no nothing, we just rawdog this shit if(charVal >= 0 && charVal <= 9) {u = 0.1 * charVal; v = 0.0;} - if(u == -1) {u = 0.8; v = 0.5;} + if(u == -1) {u = 0.8; v = 1*line_height;} tess.setNormal(0F, 1F, 0F); - tess.addVertexWithUV(0.03135, -h + yOffset, w - zOffset, u, v + 0.5); + tess.addVertexWithUV(0.03135, -h + yOffset, w - zOffset, u, v + line_height); tess.addVertexWithUV(0.03135, h + yOffset, w - zOffset, u, v); tess.addVertexWithUV(0.03135, h + yOffset, -w - zOffset, u + 0.1, v); - tess.addVertexWithUV(0.03135, -h + yOffset, -w - zOffset, u + 0.1, v + 0.5); + tess.addVertexWithUV(0.03135, -h + yOffset, -w - zOffset, u + 0.1, v + line_height); } tess.draw(); diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKNumitron.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKNumitron.java index 7356543cc..2413f13ac 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKNumitron.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKNumitron.java @@ -90,9 +90,14 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI public boolean active; /** If leading zeros should not be added */ public boolean no_leading_zeroes; + /** Which digits are activated (bit mask, msb ignored) */ + public long active_digits; + /** Display mode 0=normal, 1=integer, 2=signed hexadecimal 3=unsigned hexadecimal */ + public long display_mode; public DisplayUnit(int initialIndex) { label = "Display " + (initialIndex + 1); + active_digits = 0b01111111; } public void update() { @@ -115,6 +120,8 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI } public void serialize(ByteBuf buf) { + buf.writeLong(display_mode); + buf.writeLong(active_digits); buf.writeBoolean(no_leading_zeroes); buf.writeBoolean(active); buf.writeBoolean(polling); @@ -124,6 +131,8 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI } public void deserialize(ByteBuf buf) { + display_mode = buf.readLong(); + active_digits = buf.readLong(); no_leading_zeroes = buf.readBoolean(); active = buf.readBoolean(); polling = buf.readBoolean(); @@ -133,6 +142,8 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI } public void readFromNBT(NBTTagCompound nbt, int index) { + this.display_mode = nbt.getLong("display_mode" + index); + this.active_digits = nbt.getLong("active_digits" + index); this.no_leading_zeroes = nbt.getBoolean("no_leading_zeroes" + index); this.active = nbt.getBoolean("active" + index); this.polling = nbt.getBoolean("polling" + index); @@ -142,6 +153,8 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI } public void writeToNBT(NBTTagCompound nbt, int index) { + nbt.setLong("display_mode" + index, display_mode); + nbt.setLong("active_digits" + index, active_digits); nbt.setBoolean("no_leading_zeroes" + index, no_leading_zeroes); nbt.setBoolean("active" + index, active); nbt.setBoolean("polling" + index, polling); @@ -189,6 +202,8 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI int idx = args.checkInteger(0) - 1; if(idx < 0 || idx >= 2) return new Object[] {null, "Invalid index (1-2)"}; java.util.LinkedHashMap map = new java.util.LinkedHashMap<>(); + map.put("display_mode", displays[idx].display_mode); + map.put("active_digits", displays[idx].active_digits); map.put("no_leading_zeroes", displays[idx].no_leading_zeroes); map.put("active", displays[idx].active); map.put("polling", displays[idx].polling); @@ -258,4 +273,26 @@ public class TileEntityRBMKNumitron extends TileEntityLoadedBase implements IGUI markDirty(); return new Object[] {true}; } + + @Callback(direct = true, limit = 2) + @Optional.Method(modid = "OpenComputers") + public Object[] setDisplayActiveDigits(Context context, Arguments args) { + int idx = args.checkInteger(0) - 1; + if(idx < 0 || idx >= 2) return new Object[] {false, "Invalid index (1-2)"}; + long val = (long) args.checkInteger(1); + displays[idx].active_digits = val; + markDirty(); + return new Object[] {true}; + } + + @Callback(direct = true, limit = 2) + @Optional.Method(modid = "OpenComputers") + public Object[] setDisplayMode(Context context, Arguments args) { + int idx = args.checkInteger(0) - 1; + if(idx < 0 || idx >= 2) return new Object[] {false, "Invalid index (1-2)"}; + long val = (long) args.checkInteger(1); + displays[idx].display_mode = val; + markDirty(); + return new Object[] {true}; + } } diff --git a/src/main/java/com/hbm/util/BobMathUtil.java b/src/main/java/com/hbm/util/BobMathUtil.java index 2bd421991..a38522a07 100644 --- a/src/main/java/com/hbm/util/BobMathUtil.java +++ b/src/main/java/com/hbm/util/BobMathUtil.java @@ -193,39 +193,45 @@ public class BobMathUtil { } public static String getShortNumber(long l) { + double res; + String magnitude_letter = ""; - if(l >= Math.pow(10, 18)) { - double res = l / Math.pow(10, 18); - res = Math.round(res * 100.0) / 100.0; - return res + "E"; + if(Math.abs(l) >= Math.pow(10, 18)) { + res = l / Math.pow(10, 18); + magnitude_letter = "E"; } - if(l >= Math.pow(10, 15)) { - double res = l / Math.pow(10, 15); - res = Math.round(res * 100.0) / 100.0; - return res + "P"; + else if(Math.abs(l) >= Math.pow(10, 15)) { + res = l / Math.pow(10, 15); + magnitude_letter = "P"; } - if(l >= Math.pow(10, 12)) { - double res = l / Math.pow(10, 12); - res = Math.round(res * 100.0) / 100.0; - return res + "T"; + else if(Math.abs(l) >= Math.pow(10, 12)) { + res = l / Math.pow(10, 12); + magnitude_letter = "T"; } - if(l >= Math.pow(10, 9)) { - double res = l / Math.pow(10, 9); - res = Math.round(res * 100.0) / 100.0; - return res + "G"; + else if(Math.abs(l) >= Math.pow(10, 9)) { + res = l / Math.pow(10, 9); + magnitude_letter = "G"; } - if(l >= Math.pow(10, 6)) { - double res = l / Math.pow(10, 6); - res = Math.round(res * 100.0) / 100.0; - return res + "M"; + else if(Math.abs(l) >= Math.pow(10, 6)) { + res = l / Math.pow(10, 6); + magnitude_letter = "M"; } - if(l >= Math.pow(10, 3)) { - double res = l / Math.pow(10, 3); - res = Math.round(res * 100.0) / 100.0; - return res + "k"; + else if(Math.abs(l) >= Math.pow(10, 3)) { + res = l / Math.pow(10, 3); + magnitude_letter = "k"; + } + else { + return Long.toString(l); } - return Long.toString(l); + // Edgecase: a negative triple digit number would result in a 8 character long result so we will loose one decimal place + if (res <= -100.0) { + res = Math.round(res * 10.0) / 10.0; + } else { + res = Math.round(res * 100.0) / 100.0; + } + + return res + magnitude_letter; } /** diff --git a/src/main/resources/assets/hbm/textures/models/network/numitron_lights.png b/src/main/resources/assets/hbm/textures/models/network/numitron_lights.png index 438ad67240cb0b3f0344740fc558f5485135e237..5fd0ed71a64f8344112c57f88b33d5ce6f4b4c43 100644 GIT binary patch delta 474 zcmV<00VV#(1?K~h7k@Ma0{{R3?^>eL00001b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^ z1poj54^T{0MF0Q*X)FN0PXPbqV~02Z^7T;300009a7bBm000id000id0mpBsWB>pG zVM# z0p9VQ7p|H=fPXnk=c8wexUN1Hzcjr(0$H@16I2<$D{=tdbEKjts@B$;9hjea&TshV zz?1_K$ifMfl;+t(B^1}Z85mWBMH-FMr&xXO|I+)%_?NiLCp1{fQ*;QE>~@vUhhq{CjCYj8OUUt0dA49kMIZ$Vj}k2x|2)|FeC<)+BD_twm7M$NWEwh!K7VN=a0L zl*FYXBEedOBuM&{e{&~d?F1zI)*>`z{n{e9xKH}^UiGiqUpkT#xG~Ce^K%xb;i*4P zV_5^$O17fBwik6gH$U|Wa2E}ny`2U+0Z=bqFg#H~aP3v>qh!56yxWcCvPVd%|;@wv_fN~T00JY~?hUx7J*nj}64sC@uF%{Ewzhy-6C8O;KHyJYT#HOGKh|0?yh jvBH(=m*>1}NbSIHT+k~E{O|