infocom table

This commit is contained in:
Denis Molony 2019-04-17 19:45:29 +10:00
parent e8ae7a9cb9
commit 161c57b974
3 changed files with 199 additions and 171 deletions

View File

@ -76,7 +76,7 @@ class DiskLegendPanel extends DiskPanel
if (val > 0) if (val > 0)
{ {
g.drawString ( g.drawString (
val + " empty sector" + (val == 1 ? "" : "s") + " marked as unavailable", 10, val + " unused sector" + (val == 1 ? "" : "s") + " marked as unavailable", 10,
y); y);
y += lineHeight; y += lineHeight;
} }

View File

@ -62,7 +62,7 @@ class ObjectManager extends InfocomAbstractFile implements Iterable<ZObject>
parentNode.add (child); parentNode.add (child);
if (object.sibling > 0) if (object.sibling > 0)
buildObjectTree (header.objectManager.list.get (object.sibling - 1), parentNode, buildObjectTree (header.objectManager.list.get (object.sibling - 1), parentNode,
disk); disk);
if (object.child > 0) if (object.child > 0)
buildObjectTree (header.objectManager.list.get (object.child - 1), child, disk); buildObjectTree (header.objectManager.list.get (object.child - 1), child, disk);
else else
@ -77,13 +77,22 @@ class ObjectManager extends InfocomAbstractFile implements Iterable<ZObject>
@Override @Override
public String getText () public String getText ()
{ {
StringBuilder text = String header1 = "ID Attributes Pr Sb Ch Prop Title\n-- -----------"
new StringBuilder (" # Attributes Pr Sb Ch Prop Title\n--- -----------" + " -- -- -- ----- -----------------------------\n";
+ " -- -- -- ----- -----------------------------\n"); String underline = " --------------------------";
String header2 = "ID Title Parent Sibling"
+ " Child Attributes Prop\n" + "-- "
+ underline + underline + underline + underline + " ----------- -----" + "\n";
StringBuilder text = new StringBuilder (header2);
int objectNumber = 0; int objectNumber = 0;
for (ZObject zo : list) for (ZObject zo : list)
text.append (String.format ("%3d %s%n", ++objectNumber, zo)); if (false)
text.append (String.format ("%02X %s%n", ++objectNumber, zo));
else
text.append (
String.format ("%02X %s%n", ++objectNumber, zo.getDescription (list)));
text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1);
return text.toString (); return text.toString ();
} }

View File

@ -9,195 +9,214 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
class ZObject extends AbstractFile class ZObject extends AbstractFile
{ {
static final int HEADER_SIZE = 9; static final int HEADER_SIZE = 9;
int id; int id;
int startPtr; int startPtr;
int propertyTablePtr; int propertyTablePtr;
int propertyTableLength; int propertyTableLength;
int parent, sibling, child; int parent, sibling, child;
List<Property> properties = new ArrayList<Property> (); List<Property> properties = new ArrayList<Property> ();
Header header; Header header;
BitSet attributes = new BitSet (32); BitSet attributes = new BitSet (32);
public ZObject (String name, byte[] buffer, int offset, int seq, Header header) public ZObject (String name, byte[] buffer, int offset, int seq, Header header)
{ {
super (name, buffer); super (name, buffer);
this.header = header;
startPtr = offset; this.header = header;
id = seq; this.startPtr = offset;
id = seq;
// attributes // attributes
int bitIndex = 0; int bitIndex = 0;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
byte b = buffer[offset + i]; byte b = buffer[offset + i];
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
if ((b & 0x80) == 0x80) if ((b & 0x80) == 0x80)
attributes.set (bitIndex); attributes.set (bitIndex);
b <<= 1; b <<= 1;
++bitIndex; ++bitIndex;
} }
} }
// object's relatives // object's relatives
parent = header.getByte (offset + 4); parent = header.getByte (offset + 4);
sibling = header.getByte (offset + 5); sibling = header.getByte (offset + 5);
child = header.getByte (offset + 6); child = header.getByte (offset + 6);
// the property header contains the object's short name // the property header contains the object's short name
propertyTablePtr = header.getWord (offset + 7); propertyTablePtr = header.getWord (offset + 7);
int ptr = propertyTablePtr; int ptr = propertyTablePtr;
int nameLength = header.getByte (ptr) * 2; int nameLength = header.getByte (ptr) * 2;
this.name = nameLength == 0 ? "<<none>>" : new ZString (buffer, ++ptr, header).value; this.name = nameLength == 0 ? "<<none>>" : new ZString (buffer, ++ptr, header).value;
ptr += nameLength; ptr += nameLength;
// read each property // read each property
while (buffer[ptr] != 0) while (buffer[ptr] != 0)
{ {
Property p = new Property (buffer, ptr); Property p = new Property (buffer, ptr);
properties.add (p); properties.add (p);
ptr += p.length + 1; ptr += p.length + 1;
} }
propertyTableLength = ptr - propertyTablePtr; propertyTableLength = ptr - propertyTablePtr;
} }
@Override @Override
public String getText () public String getText ()
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append (String.format ("ID : %3d %s%n%nAttributes : ", id, name)); text.append (String.format ("ID : %3d %s%n%nAttributes : ", id, name));
text.append (HexFormatter.getHexString (buffer, startPtr, 4)); text.append (HexFormatter.getHexString (buffer, startPtr, 4));
text.append (" " + attributes.toString ()); text.append (" " + attributes.toString ());
String obj1 = parent == 0 ? "" : header.objectManager.list.get (parent - 1).name; String obj1 = parent == 0 ? "" : header.objectManager.list.get (parent - 1).name;
String obj2 = sibling == 0 ? "" : header.objectManager.list.get (sibling - 1).name; String obj2 = sibling == 0 ? "" : header.objectManager.list.get (sibling - 1).name;
String obj3 = child == 0 ? "" : header.objectManager.list.get (child - 1).name; String obj3 = child == 0 ? "" : header.objectManager.list.get (child - 1).name;
text.append (String.format ("%n%nParent : %02X (%3d) %s%n", parent, parent, obj1)); text.append (
text.append (String.format ("Sibling : %02X (%3d) %s%n", sibling, sibling, obj2)); String.format ("%n%nParent : %02X (%3d) %s%n", parent, parent, obj1));
text.append (String.format ("Child : %02X (%3d) %s%n%n", child, child, obj3)); text.append (String.format ("Sibling : %02X (%3d) %s%n", sibling, sibling, obj2));
text.append (String.format ("Child : %02X (%3d) %s%n%n", child, child, obj3));
for (Property prop : properties) for (Property prop : properties)
text.append (prop + "\n"); text.append (prop + "\n");
return text.toString (); return text.toString ();
} }
@Override @Override
public String getHexDump () public String getHexDump ()
{ {
StringBuilder text = new StringBuilder ("Header :\n\n"); StringBuilder text = new StringBuilder ("Header :\n\n");
text.append (HexFormatter.formatNoHeader (buffer, startPtr, HEADER_SIZE)); text.append (HexFormatter.formatNoHeader (buffer, startPtr, HEADER_SIZE));
text.append ("\n\nProperty table:\n\n"); text.append ("\n\nProperty table:\n\n");
text.append (HexFormatter.formatNoHeader (buffer, propertyTablePtr, propertyTableLength)); text.append (
return text.toString (); HexFormatter.formatNoHeader (buffer, propertyTablePtr, propertyTableLength));
} return text.toString ();
}
Property getProperty (int id) Property getProperty (int id)
{ {
for (Property p : properties) for (Property p : properties)
if (p.propertyNumber == id) if (p.propertyNumber == id)
return p; return p;
return null; return null;
} }
@Override @Override
public String toString () public String toString ()
{ {
return HexFormatter.getHexString (buffer, startPtr, HEADER_SIZE) + " " + name; return HexFormatter.getHexString (buffer, startPtr, HEADER_SIZE) + " " + name;
} }
class Property public String getDescription (List<ZObject> list)
{ {
int propertyNumber; StringBuilder text = new StringBuilder (String.format (" %-26s", getName ()));
int ptr;
int length;
int offset; // only used if length == 2 for (int i = 4; i < 7; i++)
{
int index = buffer[startPtr + i] & 0xFF;
String name = index > 0 ? list.get (index - 1).getName () : "";
text.append (String.format (" %-26s", name));
}
public Property (byte[] buffer, int ptr) text.append (" ");
{ text.append (HexFormatter.getHexString (buffer, startPtr, 4));
this.ptr = ptr; text.append (" ");
length = header.getByte (ptr) / 32 + 1; text.append (HexFormatter.getHexString (buffer, startPtr + 7, 2));
propertyNumber = header.getByte (ptr) % 32;
if (length == 2) return text.toString ();
offset = header.getWord (ptr + 1) * 2; }
}
private ZObject getObject () class Property
{ {
return header.objectManager.list.get ((buffer[ptr + 1] & 0xFF) - 1); int propertyNumber;
} int ptr;
int length;
int offset; // only used if length == 2
@Override public Property (byte[] buffer, int ptr)
public String toString () {
{ this.ptr = ptr;
StringBuilder text = length = header.getByte (ptr) / 32 + 1;
new StringBuilder (String.format ("%5s : ", header.propertyNames[propertyNumber])); propertyNumber = header.getByte (ptr) % 32;
String propertyType = header.propertyNames[propertyNumber]; if (length == 2)
offset = header.getWord (ptr + 1) * 2;
}
if (!propertyType.equals ("DICT") && !propertyType.contains ("STR")) private ZObject getObject ()
text.append (String.format ("%-20s", HexFormatter.getHexString (buffer, ptr + 1, length))); {
return header.objectManager.list.get ((buffer[ptr + 1] & 0xFF) - 1);
}
if (propertyType.charAt (0) >= 'a') // directions are in lowercase @Override
{ public String toString ()
switch (length) {
{ StringBuilder text = new StringBuilder (
case 1: String.format ("%5s : ", header.propertyNames[propertyNumber]));
text.append (getObject ().name);
break;
case 2:
text.append ("\"" + header.stringManager.stringAt (offset) + "\"");
break;
case 3:
int address = header.getWord (ptr + 1) * 2;
text.append (String.format ("R:%05X", address));
break;
case 4:
address = header.getWord (ptr + 3) * 2;
if (address > 0)
text.append ("\"" + header.stringManager.stringAt (address) + "\"");
break;
default:
break;
}
}
else if (propertyType.equals ("DICT"))
{
for (int i = 1; i <= length; i += 2)
{
int address = header.getWord (ptr + i);
text.append (header.wordAt (address) + ", ");
}
text.deleteCharAt (text.length () - 1);
text.deleteCharAt (text.length () - 1);
}
else if (propertyType.startsWith ("CODE"))
{
if (offset > 0) // cretin contains 00 00
{
Routine r = header.codeManager.getRoutine (offset);
if (r != null)
text.append ("\n\n" + r.getText ());
else
// this can happen if the property is mislabelled as code
text.append ("\n\n****** null routine\n");
}
}
else if (propertyType.startsWith ("STR"))
{
text
.append (String.format ("(%4X) \"%s\"", offset, header.stringManager
.stringAt (offset)));
}
return text.toString (); String propertyType = header.propertyNames[propertyNumber];
}
} if (!propertyType.equals ("DICT") && !propertyType.contains ("STR"))
text.append (
String.format ("%-20s", HexFormatter.getHexString (buffer, ptr + 1, length)));
if (propertyType.charAt (0) >= 'a') // directions are in lowercase
{
switch (length)
{
case 1:
text.append (getObject ().name);
break;
case 2:
text.append ("\"" + header.stringManager.stringAt (offset) + "\"");
break;
case 3:
int address = header.getWord (ptr + 1) * 2;
text.append (String.format ("R:%05X", address));
break;
case 4:
address = header.getWord (ptr + 3) * 2;
if (address > 0)
text.append ("\"" + header.stringManager.stringAt (address) + "\"");
break;
default:
break;
}
}
else if (propertyType.equals ("DICT"))
{
for (int i = 1; i <= length; i += 2)
{
int address = header.getWord (ptr + i);
text.append (header.wordAt (address) + ", ");
}
text.deleteCharAt (text.length () - 1);
text.deleteCharAt (text.length () - 1);
}
else if (propertyType.startsWith ("CODE"))
{
if (offset > 0) // cretin contains 00 00
{
Routine r = header.codeManager.getRoutine (offset);
if (r != null)
text.append ("\n\n" + r.getText ());
else // this can happen if the property is mislabelled as code
text.append ("\n\n****** null routine\n");
}
}
else if (propertyType.startsWith ("STR"))
{
text.append (String.format ("(%4X) \"%s\"", offset,
header.stringManager.stringAt (offset)));
}
return text.toString ();
}
}
} }