This commit is contained in:
Denis Molony 2016-03-24 10:37:59 +11:00
parent 48b95db89b
commit 8fd7bd1a29
21 changed files with 968 additions and 934 deletions

View File

@ -10,9 +10,9 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public abstract class AbstractFile implements DataSource public abstract class AbstractFile implements DataSource
{ {
public String name; protected String name;
public byte[] buffer; public byte[] buffer;
AssemblerProgram assembler; protected AssemblerProgram assembler;
protected BufferedImage image; protected BufferedImage image;
public AbstractFile (String name, byte[] buffer) public AbstractFile (String name, byte[] buffer)
@ -27,6 +27,11 @@ public abstract class AbstractFile implements DataSource
return "Name : " + name + "\n\nNo text description"; return "Name : " + name + "\n\nNo text description";
} }
public String getName ()
{
return name;
}
@Override @Override
public String getAssembler () public String getAssembler ()
{ {

View File

@ -7,143 +7,146 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class SimpleText2 extends AbstractFile public class SimpleText2 extends AbstractFile
{ {
List<Integer> lineStarts = new ArrayList<Integer> (); List<Integer> lineStarts = new ArrayList<Integer> ();
int loadAddress; int loadAddress;
boolean showByte = false; boolean showByte = false;
public SimpleText2 (String name, byte[] buffer, int loadAddress) public SimpleText2 (String name, byte[] buffer, int loadAddress)
{ {
super (name, buffer); super (name, buffer);
this.loadAddress = loadAddress; this.loadAddress = loadAddress;
// store a pointer to each new line // store a pointer to each new line
int ptr = 0; int ptr = 0;
while (buffer[ptr] != -1) while (buffer[ptr] != -1)
{ {
int length = buffer[ptr] & 0xFF; int length = buffer[ptr] & 0xFF;
lineStarts.add (ptr); lineStarts.add (ptr);
ptr += length + 1; ptr += length + 1;
} }
} }
public String getText () @Override
{ public String getText ()
StringBuilder text = new StringBuilder (); {
StringBuilder text = new StringBuilder ();
text.append ("Name : " + name + "\n"); text.append ("Name : " + name + "\n");
text.append (String.format ("Length : $%04X (%d)%n", buffer.length, buffer.length)); text.append (String.format ("Length : $%04X (%d)%n", buffer.length, buffer.length));
text.append (String.format ("Load at : $%04X%n%n", loadAddress)); text.append (String.format ("Load at : $%04X%n%n", loadAddress));
for (Integer i : lineStarts) for (Integer i : lineStarts)
text.append (String.format ("%05X %s%n", i, getLine (i))); text.append (String.format ("%05X %s%n", i, getLine (i)));
return text.toString (); return text.toString ();
} }
public String getHexDump () @Override
{ public String getHexDump ()
StringBuilder text = new StringBuilder (); {
StringBuilder text = new StringBuilder ();
for (Integer i : lineStarts) for (Integer i : lineStarts)
text.append (HexFormatter.formatNoHeader (buffer, i, (buffer[i] & 0xFF) + 1) + "\n"); text.append (HexFormatter.formatNoHeader (buffer, i, (buffer[i] & 0xFF) + 1)
text.append (HexFormatter.formatNoHeader (buffer, buffer.length - 2, 2) + "\n"); + "\n");
text.append (HexFormatter.formatNoHeader (buffer, buffer.length - 2, 2) + "\n");
return text.toString (); return text.toString ();
} }
// convert buffer to text, ignore line-break at the end // convert buffer to text, ignore line-break at the end
private String getLine (int ptr) private String getLine (int ptr)
{ {
StringBuilder line = new StringBuilder (); StringBuilder line = new StringBuilder ();
int length = buffer[ptr] & 0xFF; int length = buffer[ptr] & 0xFF;
while (--length > 0) while (--length > 0)
{ {
int val = buffer[++ptr] & 0xFF; int val = buffer[++ptr] & 0xFF;
if (val == 0xBB) if (val == 0xBB)
{ {
while (line.length () < 35) while (line.length () < 35)
line.append (' '); line.append (' ');
line.append (';'); line.append (';');
} }
else if (val >= 0x80) else if (val >= 0x80)
{ {
while (line.length () < 10) while (line.length () < 10)
line.append (' '); line.append (' ');
if (val == 0xDC) if (val == 0xDC)
line.append (String.format ("EQU", val)); line.append (String.format ("EQU %02X", val));
else if (val == 0xD0) else if (val == 0xD0)
line.append (String.format ("STA", val)); line.append (String.format ("STA %02X", val));
else if (val == 0xD2) else if (val == 0xD2)
line.append (String.format ("STY", val)); line.append (String.format ("STY %02X", val));
else if (val == 0xD4) else if (val == 0xD4)
line.append (String.format ("LSR", val)); line.append (String.format ("LSR %02X", val));
else if (val == 0xD5) else if (val == 0xD5)
line.append (String.format ("ROR", val)); line.append (String.format ("ROR %02X", val));
else if (val == 0xD7) else if (val == 0xD7)
line.append (String.format ("ASL", val)); line.append (String.format ("ASL %02X", val));
else if (val == 0xD9) else if (val == 0xD9)
line.append (String.format ("EQ ", val)); line.append (String.format ("EQ %02X", val));
else if (val == 0xDB) else if (val == 0xDB)
line.append (String.format ("TGT", val)); line.append (String.format ("TGT %02X", val));
else if (val == 0xDA) else if (val == 0xDA)
line.append (String.format ("ORG", val)); line.append (String.format ("ORG %02X", val));
else if (val == 0xB1) else if (val == 0xB1)
line.append (String.format ("TYA", val)); line.append (String.format ("TYA %02X", val));
else if (val == 0xC1) else if (val == 0xC1)
line.append (String.format ("AND", val)); line.append (String.format ("AND %02X", val));
else if (val == 0xC4) else if (val == 0xC4)
line.append (String.format ("CMP", val)); line.append (String.format ("CMP %02X", val));
else if (val == 0xC8) else if (val == 0xC8)
line.append (String.format ("EOR", val)); line.append (String.format ("EOR %02X", val));
else if (val == 0xCA) else if (val == 0xCA)
line.append (String.format ("JMP", val)); line.append (String.format ("JMP %02X", val));
else if (val == 0xCB) else if (val == 0xCB)
line.append (String.format ("JSR", val)); line.append (String.format ("JSR %02X", val));
else if (val == 0xCD) else if (val == 0xCD)
line.append (String.format ("LDA", val)); line.append (String.format ("LDA %02X", val));
else if (val == 0xCE) else if (val == 0xCE)
line.append (String.format ("LDX", val)); line.append (String.format ("LDX %02X", val));
else if (val == 0xCF) else if (val == 0xCF)
line.append (String.format ("LDY", val)); line.append (String.format ("LDY %02X", val));
else if (val == 0xA1) else if (val == 0xA1)
line.append (String.format ("PHA", val)); line.append (String.format ("PHA %02X", val));
else if (val == 0xA2) else if (val == 0xA2)
line.append (String.format ("PLA", val)); line.append (String.format ("PLA %02X", val));
else if (val == 0xA5) else if (val == 0xA5)
line.append (String.format ("RTS", val)); line.append (String.format ("RTS %02X", val));
else if (val == 0xA9) else if (val == 0xA9)
line.append (String.format ("SEC", val)); line.append (String.format ("SEC %02X", val));
else if (val == 0xAD) else if (val == 0xAD)
line.append (String.format ("TAY", val)); line.append (String.format ("TAY %02X", val));
else if (val == 0x82) else if (val == 0x82)
line.append (String.format ("BMI", val)); line.append (String.format ("BMI %02X", val));
else if (val == 0x84) else if (val == 0x84)
line.append (String.format ("BCS", val)); line.append (String.format ("BCS %02X", val));
else if (val == 0x85) else if (val == 0x85)
line.append (String.format ("BPL", val)); line.append (String.format ("BPL %02X", val));
else if (val == 0x86) else if (val == 0x86)
line.append (String.format ("BNE", val)); line.append (String.format ("BNE %02X", val));
else if (val == 0x87) else if (val == 0x87)
line.append (String.format ("BEQ", val)); line.append (String.format ("BEQ %02X", val));
else if (val == 0x99) else if (val == 0x99)
line.append (String.format ("CLC", val)); line.append (String.format ("CLC %02X", val));
else if (val == 0x9C) else if (val == 0x9C)
line.append (String.format ("DEX", val)); line.append (String.format ("DEX %02X", val));
else if (val == 0x9F) else if (val == 0x9F)
line.append (String.format ("INY", val)); line.append (String.format ("INY %02X", val));
else else
line.append (String.format (".%02X.", val)); line.append (String.format (".%02X.", val));
line.append (' '); line.append (' ');
++ptr; ++ptr;
if (buffer[ptr] < 0x20 && showByte) if (buffer[ptr] < 0x20 && showByte)
{ {
val = buffer[ptr] & 0xFF; val = buffer[ptr] & 0xFF;
line.append (String.format (".%02X. ", val)); line.append (String.format (".%02X. ", val));
} }
} }
else else
line.append ((char) val); line.append ((char) val);
} }
return line.toString (); return line.toString ();
} }
} }

View File

@ -38,7 +38,7 @@ public class VisicalcFile extends AbstractFile
debug = value; debug = value;
} }
public void setDebug (boolean value) public static void setDebug (boolean value)
{ {
debug = value; debug = value;
} }

View File

@ -11,51 +11,54 @@ import com.bytezone.diskbrowser.applefile.AppleFileSource;
public class TextDiskCreator extends AbstractDiskCreator public class TextDiskCreator extends AbstractDiskCreator
{ {
public void createDisk () @Override
{ public void createDisk ()
File f = new File ("D:\\DiskDetails.txt"); {
FileWriter out = null; File f = new File ("D:\\DiskDetails.txt");
FileWriter out = null;
try try
{ {
out = new FileWriter (f); out = new FileWriter (f);
printDisk (out); printDisk (out);
} }
catch (IOException e) catch (IOException e)
{ {
e.printStackTrace (); e.printStackTrace ();
} }
finally finally
{ {
try if (out != null)
{ try
out.close (); {
} out.close ();
catch (IOException e) }
{ catch (IOException e)
e.printStackTrace (); {
} e.printStackTrace ();
} }
} }
}
private void printDisk (FileWriter out) throws IOException private void printDisk (FileWriter out) throws IOException
{ {
Enumeration<DefaultMutableTreeNode> children = getEnumeration (); Enumeration<DefaultMutableTreeNode> children = getEnumeration ();
if (children == null) if (children == null)
return; return;
while (children.hasMoreElements ()) while (children.hasMoreElements ())
{ {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) children.nextElement (); DefaultMutableTreeNode node = children.nextElement ();
AppleFileSource afs = (AppleFileSource) node.getUserObject (); AppleFileSource afs = (AppleFileSource) node.getUserObject ();
out.write (afs.getDataSource ().getText () + String.format ("%n")); out.write (afs.getDataSource ().getText () + String.format ("%n"));
} }
} }
public String getMenuText () @Override
{ public String getMenuText ()
return "create text disk"; {
} return "create text disk";
}
} }

View File

@ -114,7 +114,7 @@ public class DirectoryEntry implements AppleFileSource
public String line () public String line ()
{ {
int blocks = ((rc & 0xF0) >> 3) + (((rc & 0x0F) + 7) / 8); // int blocks = ((rc & 0xF0) >> 3) + (((rc & 0x0F) + 7) / 8);
String bytes = HexFormatter.getHexString (blockList, 0, 16); String bytes = HexFormatter.getHexString (blockList, 0, 16);
bytes = bytes.replaceAll ("00", " "); bytes = bytes.replaceAll ("00", " ");

View File

@ -192,7 +192,11 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public String getName () public String getName ()
{ {
if (originalPath != null) if (originalPath != null)
return originalPath.getFileName ().toString (); {
Path path = originalPath.getFileName ();
if (path != null)
return path.toString ();
}
return disk.getFile ().getName (); return disk.getFile ().getName ();
} }

View File

@ -2,11 +2,11 @@ package com.bytezone.diskbrowser.disk;
public interface DiskAddress extends Comparable<DiskAddress> public interface DiskAddress extends Comparable<DiskAddress>
{ {
public int getBlock (); public int getBlock ();
public int getTrack (); public int getTrack ();
public int getSector (); public int getSector ();
public Disk getDisk (); public Disk getDisk ();
} }

View File

@ -170,58 +170,58 @@ abstract class AbstractCatalogEntry implements AppleFileSource
case Binary: // binary file case Binary: // binary file
case Relocatable: // relocatable binary file case Relocatable: // relocatable binary file
if (buffer.length == 0) // if (buffer.length == 0)
appleFile = new AssemblerProgram (name, buffer, 0); // appleFile = new AssemblerProgram (name, buffer, 0);
// else
// {
int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]);
reportedLength = HexFormatter.intValue (buffer[2], buffer[3]);
if (reportedLength == 0)
{
System.out.println (name.trim () + " reported length : 0 - reverting to "
+ (buffer.length - 4));
reportedLength = buffer.length - 4;
}
// buffer is a multiple of the block size, so it usually needs to be reduced
if ((reportedLength + 4) <= buffer.length)
{
exactBuffer = new byte[reportedLength];
// extraBuffer = new byte[buffer.length - reportedLength - 4];
// System.arraycopy (buffer, reportedLength + 4, extraBuffer, 0,
// extraBuffer.length);
}
else
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
if (ShapeTable.isShapeTable (exactBuffer))
appleFile = new ShapeTable (name, exactBuffer);
else if (HiResImage.isGif (exactBuffer))
appleFile = new HiResImage (name, exactBuffer);
else if (loadAddress == 0x2000 || loadAddress == 0x4000)
{
if ((reportedLength > 0x1F00 && reportedLength <= 0x4000)
|| ((name.equals ("FLY LOGO") && reportedLength == 0x14FA)))
appleFile = new HiResImage (name, exactBuffer);
// else if
// appleFile = new HiResImage (name, unscrunch (exactBuffer));
else
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
}
else if (name.endsWith (".S"))
appleFile = new MerlinSource (name, exactBuffer);
else else
{ {
int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]); appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
reportedLength = HexFormatter.intValue (buffer[2], buffer[3]); // System.out.printf ("%d %d%n", exactBuffer.length, reportedLength);
if (reportedLength == 0) if ((exactBuffer.length + 4) < buffer.length)
{ ((AssemblerProgram) appleFile)
System.out.println (name.trim () + " reported length : 0 - reverting to " .setExtraBuffer (buffer, exactBuffer.length + 4,
+ (buffer.length - 4)); buffer.length - (exactBuffer.length + 4));
reportedLength = buffer.length - 4;
}
// buffer is a multiple of the block size, so it usually needs to be reduced
if ((reportedLength + 4) <= buffer.length)
{
exactBuffer = new byte[reportedLength];
// extraBuffer = new byte[buffer.length - reportedLength - 4];
// System.arraycopy (buffer, reportedLength + 4, extraBuffer, 0,
// extraBuffer.length);
}
else
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
if (ShapeTable.isShapeTable (exactBuffer))
appleFile = new ShapeTable (name, exactBuffer);
else if (HiResImage.isGif (exactBuffer))
appleFile = new HiResImage (name, exactBuffer);
else if (loadAddress == 0x2000 || loadAddress == 0x4000)
{
if ((reportedLength > 0x1F00 && reportedLength <= 0x4000)
|| ((name.equals ("FLY LOGO") && reportedLength == 0x14FA)))
appleFile = new HiResImage (name, exactBuffer);
// else if
// appleFile = new HiResImage (name, unscrunch (exactBuffer));
else
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
}
else if (name.endsWith (".S"))
appleFile = new MerlinSource (name, exactBuffer);
else
{
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
// System.out.printf ("%d %d%n", exactBuffer.length, reportedLength);
if ((exactBuffer.length + 4) < buffer.length)
((AssemblerProgram) appleFile)
.setExtraBuffer (buffer, exactBuffer.length + 4,
buffer.length - (exactBuffer.length + 4));
}
} }
// }
break; break;
case SS: // what is this? case SS: // what is this?
@ -235,7 +235,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource
break; break;
case BB: // what is this? case BB: // what is this?
int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]); loadAddress = HexFormatter.intValue (buffer[0], buffer[1]);
reportedLength = HexFormatter.intValue (buffer[2], buffer[3]); reportedLength = HexFormatter.intValue (buffer[2], buffer[3]);
exactBuffer = new byte[reportedLength]; exactBuffer = new byte[reportedLength];
System.arraycopy (buffer, 4, exactBuffer, 0, reportedLength); System.arraycopy (buffer, 4, exactBuffer, 0, reportedLength);

View File

@ -23,10 +23,11 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
{ {
super (windowTitle); super (windowTitle);
State state = new State (prefs);
if (false) if (false)
{
State state = new State (prefs);
state.clear (); state.clear ();
}
JToolBar toolBar = new JToolBar ("Toolbar", JToolBar.HORIZONTAL); JToolBar toolBar = new JToolBar ("Toolbar", JToolBar.HORIZONTAL);
MenuHandler menuHandler = new MenuHandler (prefs); MenuHandler menuHandler = new MenuHandler (prefs);

View File

@ -4,14 +4,7 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import java.util.zip.Checksum; import java.util.zip.Checksum;
@ -49,8 +42,8 @@ public class TreeBuilder
public TreeBuilder (File folder) public TreeBuilder (File folder)
{ {
assert(folder.exists ()); assert (folder.exists ());
assert(folder.isDirectory ()); assert (folder.isDirectory ());
long start = System.currentTimeMillis (); long start = System.currentTimeMillis ();
@ -299,20 +292,24 @@ public class TreeBuilder
+ " Date Size Type\n"); + " Date Size Type\n");
text.append ("- ----------------------------------------" text.append ("- ----------------------------------------"
+ " ----------- -------------- ---------\n"); + " ----------- -------------- ---------\n");
for (File f : file.listFiles ())
{
String name = f.getName ();
if (name.startsWith ("."))
continue;
Date d = new Date (f.lastModified ()); File[] files = file.listFiles ();
int pos = name.lastIndexOf ('.'); if (files != null)
String type = pos > 0 && !f.isDirectory () ? name.substring (pos) : ""; for (File f : file.listFiles ())
String size = f.isDirectory () ? "" : String.format ("%,14d", f.length ()); {
text.append (String.format ("%s %-40.40s %s %-14s %s%n", String name = f.getName ();
f.isDirectory () ? "D" : " ", name, sdf.format (d), if (name.startsWith ("."))
size, type)); continue;
}
Date d = new Date (f.lastModified ());
int pos = name.lastIndexOf ('.');
String type = pos > 0 && !f.isDirectory () ? name.substring (pos) : "";
String size = f.isDirectory () ? "" : String.format ("%,14d", f.length ());
text.append (String.format ("%s %-40.40s %s %-14s %s%n",
f.isDirectory () ? "D" : " ", name, sdf.format (d),
size, type));
}
if (text.length () > 0) if (text.length () > 0)
text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1);
return text.toString (); return text.toString ();

View File

@ -11,75 +11,75 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
class AttributeManager extends AbstractFile class AttributeManager extends AbstractFile
{ {
List<Statistic> list = new ArrayList<Statistic> (); List<Statistic> list = new ArrayList<Statistic> ();
Header header; Header header;
public AttributeManager (String name, byte[] buffer, Header header) public AttributeManager (String name, byte[] buffer, Header header)
{ {
super (name, buffer); super (name, buffer);
this.header = header; this.header = header;
for (int attrNo = 0; attrNo < 32; attrNo++) for (int attrNo = 0; attrNo < 32; attrNo++)
list.add (new Statistic (attrNo)); list.add (new Statistic (attrNo));
} }
public void addNodes (DefaultMutableTreeNode node, FormattedDisk disk) public void addNodes (DefaultMutableTreeNode node, FormattedDisk disk)
{ {
node.setAllowsChildren (true); node.setAllowsChildren (true);
int count = 0; int count = 0;
for (Statistic stat : list) for (Statistic stat : list)
{ {
DefaultMutableTreeNode child = DefaultMutableTreeNode child = new DefaultMutableTreeNode (
new DefaultMutableTreeNode (new DefaultAppleFileSource (("Attribute " + count++), stat new DefaultAppleFileSource (("Attribute " + count++), stat.getText (), disk));
.getText (), disk)); node.add (child);
node.add (child); child.setAllowsChildren (false);
child.setAllowsChildren (false); }
} }
}
@Override @Override
public String getText () public String getText ()
{ {
StringBuilder text = new StringBuilder ("Attribute Frequency\n"); StringBuilder text = new StringBuilder ("Attribute Frequency\n");
text.append ("--------- ---------\n"); text.append ("--------- ---------\n");
for (Statistic stat : list) for (Statistic stat : list)
text.append (String.format ("%s%n", stat)); text.append (String.format ("%s%n", stat));
if (text.length () > 0) if (text.length () > 0)
text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1);
return text.toString (); return text.toString ();
} }
private class Statistic private class Statistic
{ {
int id; int id;
List<ZObject> list = new ArrayList<ZObject> (); List<ZObject> list = new ArrayList<ZObject> ();
public Statistic (int id) public Statistic (int id)
{ {
this.id = id; this.id = id;
for (ZObject o : header.objectManager) for (ZObject o : header.objectManager)
if (o.attributes.get (id)) if (o.attributes.get (id))
list.add (o); list.add (o);
} }
String getText () String getText ()
{ {
StringBuilder text = new StringBuilder ("Objects with attribute " + id + " set:\n\n"); StringBuilder text =
for (ZObject o : list) new StringBuilder ("Objects with attribute " + id + " set:\n\n");
{ for (ZObject o : list)
text.append (String.format ("%3d %-28s%n", o.id, o.name)); {
} text.append (String.format ("%3d %-28s%n", o.id, o.getName ()));
if (text.length () > 0) }
text.deleteCharAt (text.length () - 1); if (text.length () > 0)
return text.toString (); text.deleteCharAt (text.length () - 1);
} return text.toString ();
}
@Override @Override
public String toString () public String toString ()
{ {
return String.format (" %2d %3d", id, list.size ()); return String.format (" %2d %3d", id, list.size ());
} }
} }
} }

View File

@ -13,155 +13,158 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
class CodeManager extends AbstractFile class CodeManager extends AbstractFile
{ {
Header header; Header header;
int codeSize; int codeSize;
Map<Integer, Routine> routines = new TreeMap<Integer, Routine> (); Map<Integer, Routine> routines = new TreeMap<Integer, Routine> ();
public CodeManager (Header header) public CodeManager (Header header)
{ {
super ("Code", header.buffer); super ("Code", header.buffer);
this.header = header; this.header = header;
} }
public void addNodes (DefaultMutableTreeNode root, FormattedDisk disk) public void addNodes (DefaultMutableTreeNode root, FormattedDisk disk)
{ {
root.setAllowsChildren (true); root.setAllowsChildren (true);
codeSize = header.stringPointer - header.highMemory; // should be set by now - do this better! codeSize = header.stringPointer - header.highMemory; // should be set by now - do this better!
int count = 0; int count = 0;
for (Routine routine : routines.values ()) for (Routine routine : routines.values ())
{ {
DefaultMutableTreeNode node = DefaultMutableTreeNode node =
new DefaultMutableTreeNode (new DefaultAppleFileSource (String.format ("%3d %s (%04X)", new DefaultMutableTreeNode (new DefaultAppleFileSource (
++count, routine.name, routine.startPtr / 2), routine, disk)); String.format ("%3d %s (%04X)", ++count, routine.getName (),
node.setAllowsChildren (false); routine.startPtr / 2),
root.add (node); routine, disk));
} node.setAllowsChildren (false);
} root.add (node);
}
}
public void addMissingRoutines () public void addMissingRoutines ()
{ {
System.out.printf ("%nWalking the code block%n%n"); System.out.printf ("%nWalking the code block%n%n");
int total = 0; int total = 0;
int ptr = header.highMemory; int ptr = header.highMemory;
while (ptr < header.stringPointer)
{
if (ptr % 2 == 1) // routine must start on a word boundary
ptr++;
if (containsRoutineAt (ptr)) while (ptr < header.stringPointer)
{ {
ptr += getRoutine (ptr).length; if (ptr >= 0 && ptr % 2 == 1) // routine must start on a word boundary
continue; ptr++;
}
Routine routine = addRoutine (ptr, 0); if (containsRoutineAt (ptr))
if (routine == null) {
{ ptr += getRoutine (ptr).length;
System.out.printf ("Invalid routine found : %05X%n", ptr); continue;
ptr = findNextRoutine (ptr + 1); }
System.out.printf ("skipping to %05X%n", ptr);
if (ptr == 0)
break;
}
else
{
total++;
ptr += routine.length;
}
}
System.out.printf ("%n%d new routines found by walking the code block%n%n", total);
}
private int findNextRoutine (int address) Routine routine = addRoutine (ptr, 0);
{ if (routine == null)
for (Routine routine : routines.values ()) {
if (routine.startPtr > address) System.out.printf ("Invalid routine found : %05X%n", ptr);
return routine.startPtr; ptr = findNextRoutine (ptr + 1);
return 0; System.out.printf ("skipping to %05X%n", ptr);
} if (ptr == 0)
break;
}
else
{
total++;
ptr += routine.length;
}
}
System.out.printf ("%n%d new routines found by walking the code block%n%n", total);
}
@Override private int findNextRoutine (int address)
public String getText () {
{ for (Routine routine : routines.values ())
StringBuilder text = new StringBuilder (); if (routine.startPtr > address)
int count = 0; return routine.startPtr;
int nextAddress = header.highMemory; return 0;
text.append (" # Address Size Lines Strings Called Calls Gap Pack\n"); }
text.append ("--- ------- ---- ----- ------- ------ ----- --- ----\n");
for (Routine r : routines.values ())
{
int gap = r.startPtr - nextAddress;
text.append (String.format (
"%3d %05X %5d %3d %2d %3d %3d %4d %04X%n", ++count,
r.startPtr, r.length, r.instructions.size (), r.strings, r.calledBy.size (), r.calls
.size (), gap, r.startPtr / 2));
nextAddress = r.startPtr + r.length; @Override
} public String getText ()
text.deleteCharAt (text.length () - 1); {
return text.toString (); StringBuilder text = new StringBuilder ();
} int count = 0;
int nextAddress = header.highMemory;
text.append (" # Address Size Lines Strings Called Calls Gap Pack\n");
text.append ("--- ------- ---- ----- ------- ------ ----- --- ----\n");
for (Routine r : routines.values ())
{
int gap = r.startPtr - nextAddress;
text.append (String
.format ("%3d %05X %5d %3d %2d %3d %3d %4d %04X%n",
++count, r.startPtr, r.length, r.instructions.size (), r.strings,
r.calledBy.size (), r.calls.size (), gap, r.startPtr / 2));
public boolean containsRoutineAt (int address) nextAddress = r.startPtr + r.length;
{ }
return (routines.containsKey (address)); text.deleteCharAt (text.length () - 1);
} return text.toString ();
}
public void addCodeRoutines () public boolean containsRoutineAt (int address)
{ {
List<Integer> routines = header.objectManager.getCodeRoutines (); return (routines.containsKey (address));
System.out.println ("Adding " + routines.size () + " code routines"); }
for (Integer address : routines)
addRoutine (address, 0);
}
public void addActionRoutines () public void addCodeRoutines ()
{ {
List<Integer> routines = header.grammar.getActionRoutines (); List<Integer> routines = header.objectManager.getCodeRoutines ();
System.out.println ("Adding " + routines.size () + " action routines"); System.out.println ("Adding " + routines.size () + " code routines");
for (Integer address : routines) for (Integer address : routines)
addRoutine (address, 0); addRoutine (address, 0);
} }
public Routine addRoutine (int address, int caller) public void addActionRoutines ()
{ {
if (address == 0) // stack-based call List<Integer> routines = header.grammar.getActionRoutines ();
return null; System.out.println ("Adding " + routines.size () + " action routines");
if (address > header.fileLength) for (Integer address : routines)
return null; addRoutine (address, 0);
}
// check whether we already have this routine public Routine addRoutine (int address, int caller)
if (routines.containsKey (address)) {
{ if (address == 0) // stack-based call
Routine routine = routines.get (address); return null;
routine.addCaller (caller); if (address > header.fileLength)
return routine; return null;
}
// try to create a new Routine // check whether we already have this routine
Routine r = new Routine (address, header, caller); if (routines.containsKey (address))
if (r.length == 0) // invalid routine {
return null; Routine routine = routines.get (address);
routine.addCaller (caller);
return routine;
}
// recursively add all routines called by this one // try to create a new Routine
routines.put (address, r); Routine r = new Routine (address, header, caller);
for (int ptr : r.calls) if (r.length == 0) // invalid routine
addRoutine (ptr, address); return null;
return r; // recursively add all routines called by this one
} routines.put (address, r);
for (int ptr : r.calls)
addRoutine (ptr, address);
public Routine getRoutine (int address) return r;
{ }
return routines.get (address);
}
@Override public Routine getRoutine (int address)
public String getHexDump () {
{ return routines.get (address);
// this depends on codeSize being set after the strings have been processed }
return HexFormatter.format (buffer, header.highMemory, codeSize);
} @Override
public String getHexDump ()
{
// this depends on codeSize being set after the strings have been processed
return HexFormatter.format (buffer, header.highMemory, codeSize);
}
} }

View File

@ -128,9 +128,13 @@ public class InfocomDisk extends AbstractFormattedDisk
break; break;
} }
} }
int ptr = 255;
while (buffer[ptr--] == 0) if (buffer != null)
fileSize--; {
int ptr = 255;
while (buffer[ptr--] == 0)
fileSize--;
}
return fileSize; return fileSize;
} }

View File

@ -58,7 +58,7 @@ class ObjectManager extends InfocomAbstractFile implements Iterable<ZObject>
FormattedDisk disk) FormattedDisk disk)
{ {
DefaultMutableTreeNode child = new DefaultMutableTreeNode ( DefaultMutableTreeNode child = new DefaultMutableTreeNode (
new DefaultAppleFileSource (object.name, object, disk)); new DefaultAppleFileSource (object.getName (), object, disk));
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,

View File

@ -11,82 +11,85 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
class PropertyManager extends AbstractFile class PropertyManager extends AbstractFile
{ {
List<Statistic> list = new ArrayList<Statistic> (); List<Statistic> list = new ArrayList<Statistic> ();
Header header; Header header;
public PropertyManager (String name, byte[] buffer, Header header) public PropertyManager (String name, byte[] buffer, Header header)
{ {
super (name, buffer); super (name, buffer);
this.header = header; this.header = header;
for (int propertyNo = 1; propertyNo <= 31; propertyNo++) for (int propertyNo = 1; propertyNo <= 31; propertyNo++)
{ {
Statistic statistic = new Statistic (propertyNo); Statistic statistic = new Statistic (propertyNo);
list.add (statistic); list.add (statistic);
} }
} }
public void addNodes (DefaultMutableTreeNode node, FormattedDisk disk) public void addNodes (DefaultMutableTreeNode node, FormattedDisk disk)
{ {
node.setAllowsChildren (true); node.setAllowsChildren (true);
for (Statistic stat : list) for (Statistic stat : list)
if (stat.list.size () > 0) if (stat.list.size () > 0)
{ {
String title = "Property " + header.propertyNames[stat.id].trim (); String title = "Property " + header.propertyNames[stat.id].trim ();
DefaultMutableTreeNode child = DefaultMutableTreeNode child = new DefaultMutableTreeNode (
new DefaultMutableTreeNode (new DefaultAppleFileSource (title, stat.getText (), disk)); new DefaultAppleFileSource (title, stat.getText (), disk));
node.add (child); node.add (child);
child.setAllowsChildren (false); child.setAllowsChildren (false);
} }
} }
@Override @Override
public String getText () public String getText ()
{ {
StringBuilder text = new StringBuilder ("Property Type Frequency\n"); StringBuilder text = new StringBuilder ("Property Type Frequency\n");
text.append ("-------- ----- ---------\n"); text.append ("-------- ----- ---------\n");
for (Statistic stat : list) for (Statistic stat : list)
text.append (String.format ("%s%n", stat)); text.append (String.format ("%s%n", stat));
if (text.length () > 0) if (text.length () > 0)
text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1);
return text.toString (); return text.toString ();
} }
private class Statistic private class Statistic
{ {
int id; int id;
List<ZObject> list = new ArrayList<ZObject> (); List<ZObject> list = new ArrayList<ZObject> ();
public Statistic (int id) public Statistic (int id)
{ {
this.id = id; this.id = id;
for (ZObject o : header.objectManager) for (ZObject o : header.objectManager)
{ {
ZObject.Property p = o.getProperty (id); ZObject.Property p = o.getProperty (id);
if (p != null) if (p != null)
list.add (o); list.add (o);
} }
} }
String getText () String getText ()
{ {
StringBuilder text = new StringBuilder ("Objects with property " + id + " set:\n\n"); StringBuilder text =
for (ZObject o : list) new StringBuilder ("Objects with property " + id + " set:\n\n");
{ for (ZObject o : list)
ZObject.Property p = o.getProperty (id); {
text.append (String.format ("%3d %-29s%s%n", o.id, o.name, p.toString ().substring (7))); ZObject.Property p = o.getProperty (id);
} text.append (String.format ("%3d %-29s%s%n", o.id, o.getName (),
if (text.length () > 0) p.toString ().substring (7)));
text.deleteCharAt (text.length () - 1); }
return text.toString (); if (text.length () > 0)
} text.deleteCharAt (text.length () - 1);
return text.toString ();
}
@Override @Override
public String toString () public String toString ()
{ {
return String.format (" %2d %-6s %3d", id, header.propertyNames[id], list.size ()); return String.format (" %2d %-6s %3d", id, header.propertyNames[id],
} list.size ());
} }
}
} }

View File

@ -60,12 +60,12 @@ class PascalCodeObject implements AppleFileSource
@Override @Override
public String getUniqueName () public String getUniqueName ()
{ {
return segment.name; // this should be fileName/segmentName return segment.getName (); // this should be fileName/segmentName
} }
@Override @Override
public String toString () public String toString ()
{ {
return segment.name; return segment.getName ();
} }
} }

View File

@ -5,12 +5,12 @@ class Pi extends Function
Pi (Sheet parent, String text) Pi (Sheet parent, String text)
{ {
super (parent, text); super (parent, text);
value = Math.PI;
} }
@Override @Override
public Value calculate () public Value calculate ()
{ {
value = 3.1415926536;
return this; return this;
} }
} }

View File

@ -283,7 +283,7 @@ class Character extends AbstractFile
@Override @Override
public String toString () public String toString ()
{ {
return String.format ("%s%-15s (%d)", equipped ? "*" : " ", item.name, return String.format ("%s%-15s (%d)", equipped ? "*" : " ", item.getName (),
item.getCost ()); item.getCost ());
} }
} }

View File

@ -9,314 +9,316 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
class MazeCell class MazeCell
{ {
static Dimension cellSize = new Dimension (22, 22); // size in pixels static Dimension cellSize = new Dimension (22, 22); // size in pixels
boolean northWall; boolean northWall;
boolean southWall; boolean southWall;
boolean eastWall; boolean eastWall;
boolean westWall; boolean westWall;
boolean northDoor; boolean northDoor;
boolean southDoor; boolean southDoor;
boolean eastDoor; boolean eastDoor;
boolean westDoor; boolean westDoor;
boolean darkness; boolean darkness;
boolean stairs; boolean stairs;
boolean pit; boolean pit;
boolean spinner; boolean spinner;
boolean chute; boolean chute;
boolean elevator; boolean elevator;
boolean monsterLair; boolean monsterLair;
boolean rock; boolean rock;
boolean teleport; boolean teleport;
boolean spellsBlocked; boolean spellsBlocked;
int elevatorFrom; int elevatorFrom;
int elevatorTo; int elevatorTo;
int messageType; int messageType;
int monsterID = -1; int monsterID = -1;
int itemID; int itemID;
int unknown; int unknown;
MazeAddress address; MazeAddress address;
MazeAddress addressTo; // if teleport/stairs/chute MazeAddress addressTo; // if teleport/stairs/chute
public Message message; public Message message;
public List<Monster> monsters; public List<Monster> monsters;
public Item itemRequired; public Item itemRequired;
public Item itemObtained; public Item itemObtained;
public MazeCell (MazeAddress address) public MazeCell (MazeAddress address)
{ {
this.address = address; this.address = address;
} }
public void draw (Graphics2D g, int x, int y) public void draw (Graphics2D g, int x, int y)
{ {
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
if (westWall) if (westWall)
drawWest (g, x, y); drawWest (g, x, y);
if (eastWall) if (eastWall)
drawEast (g, x, y); drawEast (g, x, y);
if (northWall) if (northWall)
drawNorth (g, x, y); drawNorth (g, x, y);
if (southWall) if (southWall)
drawSouth (g, x, y); drawSouth (g, x, y);
g.setColor (Color.RED); g.setColor (Color.RED);
if (westDoor) if (westDoor)
drawWest (g, x, y); drawWest (g, x, y);
if (eastDoor) if (eastDoor)
drawEast (g, x, y); drawEast (g, x, y);
if (northDoor) if (northDoor)
drawNorth (g, x, y); drawNorth (g, x, y);
if (southDoor) if (southDoor)
drawSouth (g, x, y); drawSouth (g, x, y);
g.setColor (Color.GREEN); g.setColor (Color.GREEN);
if (westDoor && westWall) if (westDoor && westWall)
drawWest (g, x, y); drawWest (g, x, y);
if (eastDoor && eastWall) if (eastDoor && eastWall)
drawEast (g, x, y); drawEast (g, x, y);
if (northDoor && northWall) if (northDoor && northWall)
drawNorth (g, x, y); drawNorth (g, x, y);
if (southDoor && southWall) if (southDoor && southWall)
drawSouth (g, x, y); drawSouth (g, x, y);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
if (monsterLair) if (monsterLair)
drawMonsterLair (g, x, y); drawMonsterLair (g, x, y);
if (stairs) if (stairs)
if (address.level < addressTo.level) if (address.level < addressTo.level)
drawStairsDown (g, x, y); drawStairsDown (g, x, y);
else else
drawStairsUp (g, x, y); drawStairsUp (g, x, y);
else if (message != null) else if (message != null)
drawChar (g, x, y, "M", Color.RED); drawChar (g, x, y, "M", Color.RED);
else if (pit) else if (pit)
drawPit (g, x, y); drawPit (g, x, y);
else if (chute) else if (chute)
drawChute (g, x, y); drawChute (g, x, y);
else if (spinner) else if (spinner)
g.drawString ("S", x + 8, y + 16); g.drawString ("S", x + 8, y + 16);
else if (teleport) else if (teleport)
drawTeleport (g, x, y); drawTeleport (g, x, y);
else if (darkness) else if (darkness)
drawDarkness (g, x, y); drawDarkness (g, x, y);
else if (rock) else if (rock)
drawRock (g, x, y); drawRock (g, x, y);
else if (elevator) else if (elevator)
drawElevator (g, x, y, (elevatorTo - elevatorFrom + 1) / 2); drawElevator (g, x, y, (elevatorTo - elevatorFrom + 1) / 2);
else if (monsterID >= 0) else if (monsterID >= 0)
drawMonster (g, x, y); drawMonster (g, x, y);
else if (spellsBlocked) else if (spellsBlocked)
drawSpellsBlocked (g, x, y); drawSpellsBlocked (g, x, y);
else if (unknown != 0) else if (unknown != 0)
drawChar (g, x, y, HexFormatter.format1 (unknown), Color.GRAY); drawChar (g, x, y, HexFormatter.format1 (unknown), Color.GRAY);
} }
public void drawWest (Graphics2D g, int x, int y) public void drawWest (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 1, y + 1, x + 1, y + cellSize.height - 1); g.drawLine (x + 1, y + 1, x + 1, y + cellSize.height - 1);
} }
private void drawEast (Graphics2D g, int x, int y) private void drawEast (Graphics2D g, int x, int y)
{ {
g.drawLine (x + cellSize.width - 1, y + 1, x + cellSize.width - 1, y + cellSize.height - 1); g.drawLine (x + cellSize.width - 1, y + 1, x + cellSize.width - 1,
} y + cellSize.height - 1);
}
private void drawNorth (Graphics2D g, int x, int y) private void drawNorth (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 1, y + 1, x + cellSize.width - 1, y + 1); g.drawLine (x + 1, y + 1, x + cellSize.width - 1, y + 1);
} }
private void drawSouth (Graphics2D g, int x, int y) private void drawSouth (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 1, y + cellSize.height - 1, x + cellSize.width - 1, y + cellSize.height - 1); g.drawLine (x + 1, y + cellSize.height - 1, x + cellSize.width - 1,
} y + cellSize.height - 1);
}
public void drawStairsUp (Graphics2D g, int x, int y) public void drawStairsUp (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 6, y + 18, x + 6, y + 14); g.drawLine (x + 6, y + 18, x + 6, y + 14);
g.drawLine (x + 6, y + 14, x + 10, y + 14); g.drawLine (x + 6, y + 14, x + 10, y + 14);
g.drawLine (x + 10, y + 14, x + 10, y + 10); g.drawLine (x + 10, y + 14, x + 10, y + 10);
g.drawLine (x + 10, y + 10, x + 14, y + 10); g.drawLine (x + 10, y + 10, x + 14, y + 10);
g.drawLine (x + 14, y + 10, x + 14, y + 6); g.drawLine (x + 14, y + 10, x + 14, y + 6);
g.drawLine (x + 14, y + 6, x + 18, y + 6); g.drawLine (x + 14, y + 6, x + 18, y + 6);
} }
public void drawStairsDown (Graphics2D g, int x, int y) public void drawStairsDown (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 4, y + 7, x + 8, y + 7); g.drawLine (x + 4, y + 7, x + 8, y + 7);
g.drawLine (x + 8, y + 7, x + 8, y + 11); g.drawLine (x + 8, y + 7, x + 8, y + 11);
g.drawLine (x + 8, y + 11, x + 12, y + 11); g.drawLine (x + 8, y + 11, x + 12, y + 11);
g.drawLine (x + 12, y + 11, x + 12, y + 15); g.drawLine (x + 12, y + 11, x + 12, y + 15);
g.drawLine (x + 12, y + 15, x + 16, y + 15); g.drawLine (x + 12, y + 15, x + 16, y + 15);
g.drawLine (x + 16, y + 15, x + 16, y + 19); g.drawLine (x + 16, y + 15, x + 16, y + 19);
} }
public void drawPit (Graphics2D g, int x, int y) public void drawPit (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 5, y + 14, x + 5, y + 19); g.drawLine (x + 5, y + 14, x + 5, y + 19);
g.drawLine (x + 5, y + 19, x + 17, y + 19); g.drawLine (x + 5, y + 19, x + 17, y + 19);
g.drawLine (x + 17, y + 14, x + 17, y + 19); g.drawLine (x + 17, y + 14, x + 17, y + 19);
} }
public void drawChute (Graphics2D g, int x, int y) public void drawChute (Graphics2D g, int x, int y)
{ {
g.drawLine (x + 6, y + 6, x + 10, y + 6); g.drawLine (x + 6, y + 6, x + 10, y + 6);
g.drawLine (x + 10, y + 6, x + 18, y + 18); g.drawLine (x + 10, y + 6, x + 18, y + 18);
} }
public void drawElevator (Graphics2D g, int x, int y, int rows) public void drawElevator (Graphics2D g, int x, int y, int rows)
{ {
for (int i = 0; i < rows; i++) for (int i = 0; i < rows; i++)
{ {
g.drawOval (x + 7, y + i * 5 + 5, 2, 2); g.drawOval (x + 7, y + i * 5 + 5, 2, 2);
g.drawOval (x + 14, y + i * 5 + 5, 2, 2); g.drawOval (x + 14, y + i * 5 + 5, 2, 2);
} }
} }
public void drawMonsterLair (Graphics2D g, int x, int y) public void drawMonsterLair (Graphics2D g, int x, int y)
{ {
g.setColor (Color.YELLOW); g.setColor (Color.YELLOW);
g.fillOval (x + 4, y + 4, 2, 2); g.fillOval (x + 4, y + 4, 2, 2);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
} }
public void drawTeleport (Graphics2D g, int x, int y) public void drawTeleport (Graphics2D g, int x, int y)
{ {
g.setColor (Color.GREEN); g.setColor (Color.GREEN);
g.fillOval (x + 8, y + 8, 8, 8); g.fillOval (x + 8, y + 8, 8, 8);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
} }
public void drawSpellsBlocked (Graphics2D g, int x, int y) public void drawSpellsBlocked (Graphics2D g, int x, int y)
{ {
g.setColor (Color.YELLOW); g.setColor (Color.YELLOW);
g.fillOval (x + 8, y + 8, 8, 8); g.fillOval (x + 8, y + 8, 8, 8);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
} }
public void drawMonster (Graphics2D g, int x, int y) public void drawMonster (Graphics2D g, int x, int y)
{ {
g.setColor (Color.RED); g.setColor (Color.RED);
g.fillOval (x + 8, y + 8, 8, 8); g.fillOval (x + 8, y + 8, 8, 8);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
} }
public void drawDarkness (Graphics2D g, int x, int y) public void drawDarkness (Graphics2D g, int x, int y)
{ {
g.setColor (Color.gray); g.setColor (Color.gray);
for (int h = 0; h < 15; h += 7) for (int h = 0; h < 15; h += 7)
for (int offset = 0; offset < 15; offset += 7) for (int offset = 0; offset < 15; offset += 7)
g.drawOval (x + offset + 4, y + h + 4, 1, 1); g.drawOval (x + offset + 4, y + h + 4, 1, 1);
g.setColor (Color.white); g.setColor (Color.white);
} }
public void drawRock (Graphics2D g, int x, int y) public void drawRock (Graphics2D g, int x, int y)
{ {
for (int h = 0; h < 15; h += 7) for (int h = 0; h < 15; h += 7)
for (int offset = 0; offset < 15; offset += 7) for (int offset = 0; offset < 15; offset += 7)
g.drawOval (x + offset + 4, y + h + 4, 1, 1); g.drawOval (x + offset + 4, y + h + 4, 1, 1);
} }
public void drawChar (Graphics2D g, int x, int y, String c, Color colour) public void drawChar (Graphics2D g, int x, int y, String c, Color colour)
{ {
g.setColor (colour); g.setColor (colour);
g.fillRect (x + 7, y + 6, 11, 11); g.fillRect (x + 7, y + 6, 11, 11);
g.setColor (Color.WHITE); g.setColor (Color.WHITE);
g.drawString (c, x + 8, y + 16); g.drawString (c, x + 8, y + 16);
} }
public void drawHotDogStand (Graphics2D g, int x, int y) public void drawHotDogStand (Graphics2D g, int x, int y)
{ {
g.drawRect (x + 5, y + 11, 12, 6); g.drawRect (x + 5, y + 11, 12, 6);
g.drawOval (x + 6, y + 18, 3, 3); g.drawOval (x + 6, y + 18, 3, 3);
g.drawOval (x + 13, y + 18, 3, 3); g.drawOval (x + 13, y + 18, 3, 3);
g.drawLine (x + 8, y + 6, x + 8, y + 10); g.drawLine (x + 8, y + 6, x + 8, y + 10);
g.drawLine (x + 14, y + 6, x + 14, y + 10); g.drawLine (x + 14, y + 6, x + 14, y + 10);
g.drawLine (x + 5, y + 5, x + 17, y + 5); g.drawLine (x + 5, y + 5, x + 17, y + 5);
} }
public String getTooltipText () public String getTooltipText ()
{ {
StringBuilder sign = new StringBuilder ("<html><pre>"); StringBuilder sign = new StringBuilder ("<html><pre>");
sign.append ("&nbsp;<b>"); sign.append ("&nbsp;<b>");
sign.append (address.row + "N "); sign.append (address.row + "N ");
sign.append (address.column + "E</b>&nbsp;<br>"); sign.append (address.column + "E</b>&nbsp;<br>");
if (message != null) if (message != null)
sign.append (message.toHTMLString ()); sign.append (message.toHTMLString ());
if (elevator) if (elevator)
sign.append ("&nbsp;Elevator: L" + elevatorFrom + "-L" + elevatorTo + "&nbsp;"); sign.append ("&nbsp;Elevator: L" + elevatorFrom + "-L" + elevatorTo + "&nbsp;");
if (stairs) if (stairs)
{ {
sign.append ("&nbsp;Stairs to "); sign.append ("&nbsp;Stairs to ");
if (addressTo.level == 0) if (addressTo.level == 0)
sign.append ("castle&nbsp;"); sign.append ("castle&nbsp;");
else else
{ {
sign.append ("level " + addressTo.level + "&nbsp;"); sign.append ("level " + addressTo.level + "&nbsp;");
} }
} }
if (teleport) if (teleport)
{ {
sign.append ("&nbsp;Teleport to "); sign.append ("&nbsp;Teleport to ");
if (addressTo.level == 0) if (addressTo.level == 0)
sign.append ("castle&nbsp;"); sign.append ("castle&nbsp;");
else else
{ {
sign.append ("L" + addressTo.level + " " + addressTo.row + "N " + addressTo.column sign.append ("L" + addressTo.level + " " + addressTo.row + "N " + addressTo.column
+ "E&nbsp;"); + "E&nbsp;");
} }
} }
if (pit) if (pit)
sign.append ("&nbsp;Pit"); sign.append ("&nbsp;Pit");
if (spinner) if (spinner)
sign.append ("&nbsp;Spinner&nbsp;"); sign.append ("&nbsp;Spinner&nbsp;");
if (chute) if (chute)
sign.append ("&nbsp;Chute"); sign.append ("&nbsp;Chute");
if (darkness) if (darkness)
sign.append ("&nbsp;Darkness&nbsp;"); sign.append ("&nbsp;Darkness&nbsp;");
if (rock) if (rock)
sign.append ("&nbsp;Rock&nbsp;"); sign.append ("&nbsp;Rock&nbsp;");
if (spellsBlocked) if (spellsBlocked)
sign.append ("&nbsp;Spells fizzle out&nbsp;"); sign.append ("&nbsp;Spells fizzle out&nbsp;");
if (monsterID >= 0) if (monsterID >= 0)
if (monsters == null || monsterID >= monsters.size ()) if (monsters == null || monsterID >= monsters.size ())
sign.append ("&nbsp;Monster&nbsp;"); sign.append ("&nbsp;Monster&nbsp;");
else else
{ {
Monster monster = monsters.get (monsterID); Monster monster = monsters.get (monsterID);
sign.append ("&nbsp;<b>" + monster.getRealName () + "&nbsp;</b>"); sign.append ("&nbsp;<b>" + monster.getRealName () + "&nbsp;</b>");
while (monster.partnerOdds == 100) while (monster.partnerOdds == 100)
{ {
monster = monsters.get (monster.partnerID); monster = monsters.get (monster.partnerID);
sign.append ("<br>&nbsp;<b>" + monster.getRealName () + "&nbsp;</b>"); sign.append ("<br>&nbsp;<b>" + monster.getRealName () + "&nbsp;</b>");
} }
} }
if (itemRequired != null) if (itemRequired != null)
{ {
sign.append ("&nbsp;<b>Requires: "); sign.append ("&nbsp;<b>Requires: ");
sign.append (itemRequired.name + "&nbsp;</b>"); sign.append (itemRequired.getName () + "&nbsp;</b>");
} }
if (itemObtained != null) if (itemObtained != null)
{ {
sign.append ("&nbsp;<b>Obtain: "); sign.append ("&nbsp;<b>Obtain: ");
sign.append (itemObtained.name + "&nbsp;</b>"); sign.append (itemObtained.getName () + "&nbsp;</b>");
} }
sign.append ("</pre></html>"); sign.append ("</pre></html>");
return sign.toString (); return sign.toString ();
} }
} }

View File

@ -7,135 +7,136 @@ import com.bytezone.diskbrowser.applefile.AbstractFile;
class Reward extends AbstractFile class Reward extends AbstractFile
{ {
static String[] types = { "gold", "item" }; static String[] types = { "gold", "item" };
static final int SEGMENT_LENGTH = 18; static final int SEGMENT_LENGTH = 18;
int id; int id;
int totalElements; int totalElements;
List<RewardElement> elements; List<RewardElement> elements;
List<Item> items; List<Item> items;
List<Monster> goldMonsters = new ArrayList<Monster> (); List<Monster> goldMonsters = new ArrayList<Monster> ();
List<Monster> chestMonsters = new ArrayList<Monster> (); List<Monster> chestMonsters = new ArrayList<Monster> ();
public Reward (String name, byte[] buffer, int id, List<Item> items) public Reward (String name, byte[] buffer, int id, List<Item> items)
{ {
super (name, buffer); super (name, buffer);
this.id = id; this.id = id;
this.items = items; this.items = items;
totalElements = buffer[4]; totalElements = buffer[4];
elements = new ArrayList<RewardElement> (totalElements); elements = new ArrayList<RewardElement> (totalElements);
for (int i = 0; i < totalElements; i++) for (int i = 0; i < totalElements; i++)
{ {
byte[] buffer2 = new byte[SEGMENT_LENGTH]; byte[] buffer2 = new byte[SEGMENT_LENGTH];
System.arraycopy (buffer, i * SEGMENT_LENGTH, buffer2, 0, SEGMENT_LENGTH); System.arraycopy (buffer, i * SEGMENT_LENGTH, buffer2, 0, SEGMENT_LENGTH);
elements.add (new RewardElement (buffer2)); elements.add (new RewardElement (buffer2));
} }
} }
public void addMonster (Monster monster, int location) public void addMonster (Monster monster, int location)
{ {
if (location == 0) if (location == 0)
goldMonsters.add (monster); goldMonsters.add (monster);
else else
chestMonsters.add (monster); chestMonsters.add (monster);
} }
@Override @Override
public String getText () public String getText ()
{ {
return getText (true); return getText (true);
} }
public String getText (boolean showLinks) public String getText (boolean showLinks)
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
for (RewardElement re : elements) for (RewardElement re : elements)
text.append (re.getDetail () + "\n"); text.append (re.getDetail () + "\n");
if (showLinks) if (showLinks)
{ {
if (goldMonsters.size () > 0) if (goldMonsters.size () > 0)
{ {
text.append ("Without chest:\n\n"); text.append ("Without chest:\n\n");
for (Monster m : goldMonsters) for (Monster m : goldMonsters)
text.append (" " + m + "\n"); text.append (" " + m + "\n");
text.append ("\n"); text.append ("\n");
} }
if (chestMonsters.size () > 0) if (chestMonsters.size () > 0)
{ {
text.append ("With chest:\n\n"); text.append ("With chest:\n\n");
for (Monster m : chestMonsters) for (Monster m : chestMonsters)
text.append (" " + m + "\n"); text.append (" " + m + "\n");
} }
} }
return text.toString (); return text.toString ();
} }
public String getDump () public String getDump ()
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
int seq = 0; int seq = 0;
for (RewardElement re : elements) for (RewardElement re : elements)
{ {
text.append (seq++ == 0 ? String.format ("%02X : ", id) : " "); text.append (seq++ == 0 ? String.format ("%02X : ", id) : " ");
text.append (re + "\n"); text.append (re + "\n");
} }
return text.toString (); return text.toString ();
} }
private class RewardElement private class RewardElement
{ {
int type; int type;
int odds; int odds;
byte[] buffer; byte[] buffer;
public RewardElement (byte[] buffer) public RewardElement (byte[] buffer)
{ {
this.buffer = buffer; this.buffer = buffer;
type = buffer[8]; type = buffer[8];
odds = buffer[6]; odds = buffer[6];
} }
@Override @Override
public String toString () public String toString ()
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
for (int i = 0; i < SEGMENT_LENGTH; i += 2) for (int i = 0; i < SEGMENT_LENGTH; i += 2)
text.append (String.format ("%3d ", buffer[i] & 0xFF)); text.append (String.format ("%3d ", buffer[i] & 0xFF));
return text.toString (); return text.toString ();
} }
public String getDetail () public String getDetail ()
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Odds ............ " + odds + "%\n"); text.append ("Odds ............ " + odds + "%\n");
switch (type) switch (type)
{ {
case 0: case 0:
text.append ("Gold ............ " + buffer[10] + "d" + buffer[12] + "\n"); text.append ("Gold ............ " + buffer[10] + "d" + buffer[12] + "\n");
break; break;
case 1: case 1:
int lo = buffer[10] & 0xFF; int lo = buffer[10] & 0xFF;
int qty = buffer[16] & 0xFF; int qty = buffer[16] & 0xFF;
boolean title = true; boolean title = true;
String[] lineItem = new String[4]; String[] lineItem = new String[4];
for (int i = lo, max = lo + qty; i <= max; i += lineItem.length) for (int i = lo, max = lo + qty; i <= max; i += lineItem.length)
{ {
String lineTitle = title ? "Items ..........." : ""; String lineTitle = title ? "Items ..........." : "";
title = false; title = false;
for (int j = 0; j < lineItem.length; j++) for (int j = 0; j < lineItem.length; j++)
lineItem[j] = i + j <= max ? items.get (i + j).name : ""; lineItem[j] = i + j <= max ? items.get (i + j).getName () : "";
text.append (String.format ("%-17s %-16s %-16s %-16s %-16s%n", lineTitle, lineItem[0], text.append (String.format ("%-17s %-16s %-16s %-16s %-16s%n", lineTitle,
lineItem[1], lineItem[2], lineItem[3])); lineItem[0], lineItem[1], lineItem[2],
} lineItem[3]));
break; }
default: break;
System.out.println ("Unknown reward type " + type); default:
} System.out.println ("Unknown reward type " + type);
}
return text.toString (); return text.toString ();
} }
} }
} }

View File

@ -9,7 +9,11 @@ import javax.swing.tree.DefaultTreeModel;
import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.disk.*; import com.bytezone.diskbrowser.disk.DefaultAppleFileSource;
import com.bytezone.diskbrowser.disk.DefaultDataSource;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.SectorType;
import com.bytezone.diskbrowser.gui.DataSource; import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -93,7 +97,8 @@ public class WizardryScenarioDisk extends PascalDisk
extractMonsters (linkNode ("Monsters", "Monsters string", dataNode), sectors); extractMonsters (linkNode ("Monsters", "Monsters string", dataNode), sectors);
extractCharacters (linkNode ("Characters", "Characters string", dataNode), sectors); extractCharacters (linkNode ("Characters", "Characters string", dataNode), sectors);
extractImages (linkNode ("Images", "Images string", dataNode), sectors); extractImages (linkNode ("Images", "Images string", dataNode), sectors);
extractExperienceLevels (linkNode ("Experience", "Experience string", dataNode), sectors); extractExperienceLevels (linkNode ("Experience", "Experience string", dataNode),
sectors);
// node = linkNode ("Spells", "Spells string", dataNode); // node = linkNode ("Spells", "Spells string", dataNode);
node = null; node = null;
extractSpells (node, sectors); extractSpells (node, sectors);
@ -112,7 +117,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private DefaultMutableTreeNode linkNode (String name, String text, private DefaultMutableTreeNode linkNode (String name, String text,
DefaultMutableTreeNode parent) DefaultMutableTreeNode parent)
{ {
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this); DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs); DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
@ -133,7 +138,7 @@ public class WizardryScenarioDisk extends PascalDisk
{ {
String text = HexFormatter.getPascalString (buffer, ptr); String text = HexFormatter.getPascalString (buffer, ptr);
if (!text.equals ("SCENARIO.DATA") && !text.equals ("SCENARIO.MESGS") if (!text.equals ("SCENARIO.DATA") && !text.equals ("SCENARIO.MESGS")
&& !text.equals ("WIZARDRY.CODE")) && !text.equals ("WIZARDRY.CODE"))
return false; return false;
} }
return true; return true;
@ -189,8 +194,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private int addReward (byte[] buffer, List<DiskAddress> blocks, DefaultMutableTreeNode node, private int addReward (byte[] buffer, List<DiskAddress> blocks,
int seq) DefaultMutableTreeNode node, int seq)
{ {
int recLen = 168; int recLen = 168;
for (int ptr = 0; ptr < 1008; ptr += recLen) for (int ptr = 0; ptr < 1008; ptr += recLen)
@ -224,9 +229,9 @@ public class WizardryScenarioDisk extends PascalDisk
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Name Age Align Race Type " text.append ("Name Age Align Race Type "
+ "HP St In Pi Vi Ag Lu Status\n"); + "HP St In Pi Vi Ag Lu Status\n");
text.append ("------------- ---- -------- -------- ---------- " text.append ("------------- ---- -------- -------- ---------- "
+ "-- -- -- -- -- -- -- ------\n"); + "-- -- -- -- -- -- -- ------\n");
for (Character ch : characters) for (Character ch : characters)
{ {
Statistics stats = ch.getStatistics (); Statistics stats = ch.getStatistics ();
@ -237,7 +242,8 @@ public class WizardryScenarioDisk extends PascalDisk
text.append (String.format (" %2d %2d %2d %2d %2d %2d", att.strength, text.append (String.format (" %2d %2d %2d %2d %2d %2d", att.strength,
att.intelligence, att.piety, att.vitality, att.agility, att.intelligence, att.piety, att.vitality, att.agility,
att.luck)); att.luck));
text.append (String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : "")); text.append (String.format (" %5s %s%n", stats.status,
ch.isOut () ? "* OUT *" : ""));
} }
DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject (); DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject ();
@ -247,7 +253,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addCharacters (byte[] buffer, List<DiskAddress> blocks, private void addCharacters (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node) DefaultMutableTreeNode node)
{ {
int recLen = 208; int recLen = 208;
for (int ptr = 0; ptr < 832; ptr += recLen) for (int ptr = 0; ptr < 832; ptr += recLen)
@ -300,7 +306,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addMonsters (byte[] buffer, List<DiskAddress> blocks, private void addMonsters (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node) DefaultMutableTreeNode node)
{ {
int recLen = 158; int recLen = 158;
for (int ptr = 0; ptr < 948; ptr += recLen) for (int ptr = 0; ptr < 948; ptr += recLen)
@ -352,7 +358,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private void addItems (byte[] buffer, List<DiskAddress> blocks, DefaultMutableTreeNode node) private void addItems (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node)
{ {
int recLen = 78; int recLen = 78;
for (int ptr = 0; ptr < 1014; ptr += recLen) for (int ptr = 0; ptr < 1014; ptr += recLen)
@ -493,7 +500,7 @@ public class WizardryScenarioDisk extends PascalDisk
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
for (MazeLevel level : levels) for (MazeLevel level : levels)
text.append (level.name + "\n"); text.append (level.getName () + "\n");
DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject (); DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject ();
afs.setSectors (nodeSectors); afs.setSectors (nodeSectors);
@ -524,16 +531,15 @@ public class WizardryScenarioDisk extends PascalDisk
break; break;
} }
AbstractImage mi = AbstractImage mi = scenarioHeader.scenarioID < 3 ? new Image (name, buffer)
scenarioHeader.scenarioID < 3 ? new Image (name, buffer) : new ImageV2 (name, : new ImageV2 (name, exactBuffer);
exactBuffer);
images.add (mi); images.add (mi);
addToNode (mi, node, da, imageSector); addToNode (mi, node, da, imageSector);
} }
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
for (AbstractImage image : images) for (AbstractImage image : images)
text.append (image.name + "\n"); text.append (image.getName () + "\n");
DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject (); DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject ();
afs.setSectors (nodeSectors); afs.setSectors (nodeSectors);
@ -541,8 +547,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private void private void extractExperienceLevels (DefaultMutableTreeNode node,
extractExperienceLevels (DefaultMutableTreeNode node, List<DiskAddress> sectors) List<DiskAddress> sectors)
{ {
List<DiskAddress> nodeSectors = new ArrayList<DiskAddress> (); List<DiskAddress> nodeSectors = new ArrayList<DiskAddress> ();
ScenarioData sd = scenarioHeader.data.get (Header.EXPERIENCE_AREA); ScenarioData sd = scenarioHeader.data.get (Header.EXPERIENCE_AREA);
@ -573,7 +579,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addToNode (AbstractFile af, DefaultMutableTreeNode node, DiskAddress block, private void addToNode (AbstractFile af, DefaultMutableTreeNode node, DiskAddress block,
SectorType type) SectorType type)
{ {
ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (1); ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (1);
blocks.add (block); blocks.add (block);
@ -581,15 +587,17 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addToNode (AbstractFile af, DefaultMutableTreeNode node, private void addToNode (AbstractFile af, DefaultMutableTreeNode node,
List<DiskAddress> blocks, SectorType type) List<DiskAddress> blocks, SectorType type)
{ {
DefaultAppleFileSource dafs = new DefaultAppleFileSource (af.name, af, this, blocks); DefaultAppleFileSource dafs =
new DefaultAppleFileSource (af.getName (), af, this, blocks);
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (dafs); DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (dafs);
node.add (childNode); node.add (childNode);
childNode.setAllowsChildren (false); childNode.setAllowsChildren (false);
} }
private List<DiskAddress> getTwoBlocks (ScenarioData sd, int i, List<DiskAddress> sectors) private List<DiskAddress> getTwoBlocks (ScenarioData sd, int i,
List<DiskAddress> sectors)
{ {
ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (2); ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (2);
blocks.add (sectors.get (sd.dataOffset + i * 2)); blocks.add (sectors.get (sd.dataOffset + i * 2));