mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-09-29 22:54:45 +00:00
227 lines
7.0 KiB
Java
227 lines
7.0 KiB
Java
|
package com.bytezone.diskbrowser.wizardry;
|
||
|
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||
|
|
||
|
import com.bytezone.diskbrowser.HexFormatter;
|
||
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||
|
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
|
||
|
import com.bytezone.diskbrowser.disk.DefaultAppleFileSource;
|
||
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
||
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||
|
|
||
|
class Header
|
||
|
{
|
||
|
static String[] typeText =
|
||
|
{ "header", "maze", "monsters", "rewards", "items", "characters", "images", "char levels" };
|
||
|
static String[] scenarioNames =
|
||
|
{ "PROVING GROUNDS OF THE MAD OVERLORD!", "THE KNIGHT OF DIAMONDS",
|
||
|
"THE LEGACY OF LLYLGAMYN" };
|
||
|
|
||
|
static final int MAZE_AREA = 1;
|
||
|
static final int MONSTER_AREA = 2;
|
||
|
static final int TREASURE_TABLE_AREA = 3;
|
||
|
static final int ITEM_AREA = 4;
|
||
|
static final int CHARACTER_AREA = 5;
|
||
|
static final int IMAGE_AREA = 6;
|
||
|
static final int EXPERIENCE_AREA = 7;
|
||
|
|
||
|
String scenarioTitle;
|
||
|
public int scenarioID;
|
||
|
List<ScenarioData> data = new ArrayList<ScenarioData> (8);
|
||
|
FormattedDisk owner;
|
||
|
|
||
|
public Header (DefaultMutableTreeNode dataNode, FormattedDisk owner)
|
||
|
{
|
||
|
this.owner = owner;
|
||
|
|
||
|
AppleFileSource afs = (AppleFileSource) dataNode.getUserObject ();
|
||
|
List<DiskAddress> sectors = afs.getSectors ();
|
||
|
DefaultAppleFile daf = (DefaultAppleFile) afs.getDataSource ();
|
||
|
scenarioTitle = HexFormatter.getPascalString (daf.buffer, 0);
|
||
|
|
||
|
while (scenarioID < scenarioNames.length)
|
||
|
if (scenarioNames[scenarioID++].equals (scenarioTitle))
|
||
|
break;
|
||
|
assert (scenarioID <= scenarioNames.length) : "Invalid scenario ID : " + scenarioID;
|
||
|
|
||
|
for (int i = 0; i < 8; i++)
|
||
|
data.add (new ScenarioData (daf.buffer, i, sectors));
|
||
|
|
||
|
StringBuilder text =
|
||
|
new StringBuilder ("Data type Offset Size Units ???\n"
|
||
|
+ "------------ ------ ----- ----- -----\n");
|
||
|
|
||
|
for (ScenarioData sd : data)
|
||
|
text.append (sd + "\n");
|
||
|
|
||
|
daf.setText (text.toString ());
|
||
|
|
||
|
text = new StringBuilder (scenarioTitle + "\n\n");
|
||
|
|
||
|
int ptr = 106;
|
||
|
while (daf.buffer[ptr] != -1)
|
||
|
{
|
||
|
text.append (HexFormatter.getPascalString (daf.buffer, ptr) + "\n");
|
||
|
ptr += 10;
|
||
|
}
|
||
|
|
||
|
DefaultAppleFileSource dafs = new DefaultAppleFileSource ("Header", text.toString (), owner);
|
||
|
dafs.setSectors (data.get (0).sectors);
|
||
|
DefaultMutableTreeNode headerNode = new DefaultMutableTreeNode (dafs);
|
||
|
dataNode.add (headerNode);
|
||
|
|
||
|
int totalBlocks = data.get (0).sectors.size ();
|
||
|
linkText ("Text", data.get (0).sectors.get (0), headerNode);
|
||
|
if (scenarioID < 3)
|
||
|
{
|
||
|
linkPictures ("Alphabet", data.get (0).sectors.get (1), headerNode);
|
||
|
linkPictures ("Graphics", data.get (0).sectors.get (2), headerNode);
|
||
|
linkPictures ("Unknown", data.get (0).sectors.get (3), headerNode);
|
||
|
}
|
||
|
linkSpells ("Mage spells", data.get (0).sectors.get (totalBlocks - 2), headerNode);
|
||
|
linkSpells ("Priest spells", data.get (0).sectors.get (totalBlocks - 1), headerNode);
|
||
|
|
||
|
if (false && scenarioID <= 2)
|
||
|
{
|
||
|
System.out.println (printChars (daf.buffer, 1));
|
||
|
System.out.println (printChars (daf.buffer, 2));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void linkText (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
|
||
|
{
|
||
|
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
|
||
|
blocks.add (da);
|
||
|
|
||
|
StringBuilder text = new StringBuilder (scenarioTitle + "\n\n");
|
||
|
|
||
|
int ptr = 106;
|
||
|
byte[] buffer = owner.getDisk ().readSector (da);
|
||
|
while (buffer[ptr] != -1)
|
||
|
{
|
||
|
text.append (HexFormatter.getPascalString (buffer, ptr) + "\n");
|
||
|
ptr += 10;
|
||
|
}
|
||
|
ptr += 2;
|
||
|
text.append ("\n");
|
||
|
while (ptr < 512)
|
||
|
{
|
||
|
int value = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]);
|
||
|
text.append (String.format ("%04X %,6d%n", value, value));
|
||
|
ptr += 2;
|
||
|
}
|
||
|
|
||
|
DefaultAppleFileSource dafs = new DefaultAppleFileSource (title, text.toString (), owner);
|
||
|
dafs.setSectors (blocks);
|
||
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
|
||
|
node.setAllowsChildren (false);
|
||
|
headerNode.add (node);
|
||
|
}
|
||
|
|
||
|
private void linkPictures (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
|
||
|
{
|
||
|
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
|
||
|
blocks.add (da);
|
||
|
|
||
|
byte[] buffer = owner.getDisk ().readSector (da);
|
||
|
String text = printChars (buffer, 0);
|
||
|
|
||
|
DefaultAppleFileSource dafs = new DefaultAppleFileSource (title, text, owner);
|
||
|
dafs.setSectors (blocks);
|
||
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
|
||
|
node.setAllowsChildren (false);
|
||
|
headerNode.add (node);
|
||
|
}
|
||
|
|
||
|
private void linkSpells (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
|
||
|
{
|
||
|
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
|
||
|
blocks.add (da);
|
||
|
int level = 1;
|
||
|
|
||
|
StringBuilder list = new StringBuilder ("Level " + level + ":\n");
|
||
|
byte[] buffer = owner.getDisk ().readSector (da);
|
||
|
String text = HexFormatter.getString (buffer, 0, 512);
|
||
|
String[] spells = text.split ("\n");
|
||
|
for (String s : spells)
|
||
|
{
|
||
|
if (s.length () == 0)
|
||
|
break;
|
||
|
if (s.startsWith ("*"))
|
||
|
{
|
||
|
s = s.substring (1);
|
||
|
level++;
|
||
|
list.append ("\nLevel " + level + ":\n");
|
||
|
}
|
||
|
list.append (" " + s + "\n");
|
||
|
}
|
||
|
|
||
|
DefaultAppleFileSource dafs = new DefaultAppleFileSource (title, list.toString (), owner);
|
||
|
dafs.setSectors (blocks);
|
||
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
|
||
|
node.setAllowsChildren (false);
|
||
|
headerNode.add (node);
|
||
|
}
|
||
|
|
||
|
private String printChars (byte[] buffer, int block)
|
||
|
{
|
||
|
StringBuilder text = new StringBuilder ();
|
||
|
for (int i = block * 512; i < (block + 1) * 512; i += 64)
|
||
|
{
|
||
|
for (int line = 0; line < 8; line++)
|
||
|
{
|
||
|
for (int j = 0; j < 8; j++)
|
||
|
{
|
||
|
int value = HexFormatter.intValue (buffer[i + line + j * 8]);
|
||
|
for (int bit = 0; bit < 7; bit++)
|
||
|
{
|
||
|
if ((value & 0x01) == 1)
|
||
|
text.append ("O");
|
||
|
else
|
||
|
text.append (".");
|
||
|
value >>= 1;
|
||
|
}
|
||
|
text.append (" ");
|
||
|
}
|
||
|
text.append ("\n");
|
||
|
}
|
||
|
text.append ("\n");
|
||
|
}
|
||
|
return text.toString ();
|
||
|
}
|
||
|
|
||
|
// this could be the base factory class for all Wizardry types
|
||
|
class ScenarioData
|
||
|
{
|
||
|
int dunno;
|
||
|
int total;
|
||
|
int totalBlocks;
|
||
|
int dataOffset;
|
||
|
int type;
|
||
|
List<DiskAddress> sectors;
|
||
|
|
||
|
public ScenarioData (byte[] buffer, int seq, List<DiskAddress> sectors)
|
||
|
{
|
||
|
int offset = 42 + seq * 2;
|
||
|
dunno = HexFormatter.intValue (buffer[offset]);
|
||
|
total = HexFormatter.intValue (buffer[offset + 16]);
|
||
|
totalBlocks = HexFormatter.intValue (buffer[offset + 32]);
|
||
|
dataOffset = HexFormatter.intValue (buffer[offset + 48]);
|
||
|
type = seq;
|
||
|
|
||
|
this.sectors = new ArrayList<DiskAddress> (totalBlocks);
|
||
|
for (int i = dataOffset, max = dataOffset + totalBlocks; i < max; i++)
|
||
|
this.sectors.add (sectors.get (i));
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String toString ()
|
||
|
{
|
||
|
return String.format ("%-15s %3d %3d %3d %3d", typeText[type], dataOffset,
|
||
|
totalBlocks, total, dunno);
|
||
|
}
|
||
|
}
|
||
|
}
|