mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-09-28 15:55:34 +00:00
infocom table
This commit is contained in:
parent
e8ae7a9cb9
commit
161c57b974
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
@ -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 ();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user