Hexadecimal Display, Negative Number Display Fix, Active Digit Selection

This commit is contained in:
DaSH 2026-04-28 02:17:43 +02:00
parent 1b1dc6f998
commit 92c86a5719
4 changed files with 157 additions and 40 deletions

View File

@ -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();

View File

@ -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<String, Object> 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};
}
}

View File

@ -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;
}
/**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 712 B

After

Width:  |  Height:  |  Size: 487 B