Wiz4 messages

This commit is contained in:
Denis Molony 2016-08-16 16:34:23 +10:00
parent 78babc4d2c
commit 1f3894f162
7 changed files with 545 additions and 222 deletions

View File

@ -55,7 +55,7 @@ public class HexFormatter
{ {
if (line.length () > 0 && i > 0) if (line.length () > 0 && i > 0)
line.append ("\n"); line.append ("\n");
if (i > 0 && (i % 0x200) == 0) if (i > offset && (i % 0x200) == 0)
line.append ("\n"); line.append ("\n");
// print offset // print offset

View File

@ -14,214 +14,226 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
class Header class Header
{ {
static String[] typeText = static String[] typeText = { "header", "maze", "monsters", "rewards", "items",
{ "header", "maze", "monsters", "rewards", "items", "characters", "images", "char levels" }; "characters", "images", "char levels" };
static String[] scenarioNames = static String[] scenarioNames =
{ "PROVING GROUNDS OF THE MAD OVERLORD!", "THE KNIGHT OF DIAMONDS", { "PROVING GROUNDS OF THE MAD OVERLORD!", "THE KNIGHT OF DIAMONDS",
"THE LEGACY OF LLYLGAMYN" }; "THE LEGACY OF LLYLGAMYN", "THE RETURN OF WERDNA" };
static final int MAZE_AREA = 1; static final int MAZE_AREA = 1;
static final int MONSTER_AREA = 2; static final int MONSTER_AREA = 2;
static final int TREASURE_TABLE_AREA = 3; static final int TREASURE_TABLE_AREA = 3;
static final int ITEM_AREA = 4; static final int ITEM_AREA = 4;
static final int CHARACTER_AREA = 5; static final int CHARACTER_AREA = 5;
static final int IMAGE_AREA = 6; static final int IMAGE_AREA = 6;
static final int EXPERIENCE_AREA = 7; static final int EXPERIENCE_AREA = 7;
String scenarioTitle; String scenarioTitle;
public int scenarioID; public int scenarioID;
List<ScenarioData> data = new ArrayList<ScenarioData> (8); List<ScenarioData> data = new ArrayList<ScenarioData> (8);
FormattedDisk owner; FormattedDisk owner;
public Header (DefaultMutableTreeNode dataNode, FormattedDisk owner) public Header (DefaultMutableTreeNode dataNode, FormattedDisk owner)
{ {
this.owner = owner; this.owner = owner;
AppleFileSource afs = (AppleFileSource) dataNode.getUserObject (); AppleFileSource afs = (AppleFileSource) dataNode.getUserObject ();
List<DiskAddress> sectors = afs.getSectors (); List<DiskAddress> sectors = afs.getSectors ();
DefaultAppleFile daf = (DefaultAppleFile) afs.getDataSource (); DefaultAppleFile daf = (DefaultAppleFile) afs.getDataSource ();
scenarioTitle = HexFormatter.getPascalString (daf.buffer, 0); scenarioTitle = HexFormatter.getPascalString (daf.buffer, 0);
while (scenarioID < scenarioNames.length) while (scenarioID < scenarioNames.length)
if (scenarioNames[scenarioID++].equals (scenarioTitle)) if (scenarioNames[scenarioID++].equals (scenarioTitle))
break; break;
assert (scenarioID <= scenarioNames.length) : "Invalid scenario ID : " + scenarioID;
for (int i = 0; i < 8; i++) if (scenarioID > scenarioNames.length)
data.add (new ScenarioData (daf.buffer, i, sectors)); System.out.println ("Invalid scenario ID : " + scenarioID + " " + scenarioTitle);
StringBuilder text = for (int i = 0; i < 8; i++)
new StringBuilder ("Data type Offset Size Units ???\n" data.add (new ScenarioData (daf.buffer, i, sectors));
+ "------------ ------ ----- ----- -----\n");
for (ScenarioData sd : data) StringBuilder text = new StringBuilder ("Data type Offset Size Units ???\n"
text.append (sd + "\n"); + "------------ ------ ----- ----- -----\n");
daf.setText (text.toString ()); for (ScenarioData sd : data)
text.append (sd + "\n");
text = new StringBuilder (scenarioTitle + "\n\n"); daf.setText (text.toString ());
int ptr = 106; text = new StringBuilder (scenarioTitle + "\n\n");
while (daf.buffer[ptr] != -1)
{
text.append (HexFormatter.getPascalString (daf.buffer, ptr) + "\n");
ptr += 10;
}
DefaultAppleFileSource dafs = new DefaultAppleFileSource ("Header", text.toString (), owner); int ptr = 106;
dafs.setSectors (data.get (0).sectors); while (daf.buffer[ptr] != -1)
DefaultMutableTreeNode headerNode = new DefaultMutableTreeNode (dafs); {
dataNode.add (headerNode); text.append (HexFormatter.getPascalString (daf.buffer, ptr) + "\n");
ptr += 10;
}
int totalBlocks = data.get (0).sectors.size (); DefaultAppleFileSource dafs =
linkText ("Text", data.get (0).sectors.get (0), headerNode); new DefaultAppleFileSource ("Header", text.toString (), owner);
if (scenarioID < 3) dafs.setSectors (data.get (0).sectors);
{ DefaultMutableTreeNode headerNode = new DefaultMutableTreeNode (dafs);
linkPictures ("Alphabet", data.get (0).sectors.get (1), headerNode); dataNode.add (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) if (scenarioID > 3)
{ return;
System.out.println (printChars (daf.buffer, 1));
System.out.println (printChars (daf.buffer, 2));
}
}
private void linkText (String title, DiskAddress da, DefaultMutableTreeNode headerNode) int totalBlocks = data.get (0).sectors.size ();
{ linkText ("Text", data.get (0).sectors.get (0), headerNode);
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
blocks.add (da);
StringBuilder text = new StringBuilder (scenarioTitle + "\n\n"); 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);
}
int ptr = 106; linkSpells ("Mage spells", data.get (0).sectors.get (totalBlocks - 2), headerNode);
byte[] buffer = owner.getDisk ().readSector (da); linkSpells ("Priest spells", data.get (0).sectors.get (totalBlocks - 1), headerNode);
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); if (false && scenarioID <= 2)
dafs.setSectors (blocks); {
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs); System.out.println (printChars (daf.buffer, 1));
node.setAllowsChildren (false); System.out.println (printChars (daf.buffer, 2));
headerNode.add (node); }
} }
private void linkPictures (String title, DiskAddress da, DefaultMutableTreeNode headerNode) private void linkText (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
{ {
List<DiskAddress> blocks = new ArrayList<DiskAddress> (); List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
blocks.add (da); blocks.add (da);
byte[] buffer = owner.getDisk ().readSector (da); StringBuilder text = new StringBuilder (scenarioTitle + "\n\n");
String text = printChars (buffer, 0);
DefaultAppleFileSource dafs = new DefaultAppleFileSource (title, text, owner); int ptr = 106;
dafs.setSectors (blocks); byte[] buffer = owner.getDisk ().readSector (da);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs); while (buffer[ptr] != -1)
node.setAllowsChildren (false); {
headerNode.add (node); 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;
}
private void linkSpells (String title, DiskAddress da, DefaultMutableTreeNode headerNode) DefaultAppleFileSource dafs =
{ new DefaultAppleFileSource (title, text.toString (), owner);
List<DiskAddress> blocks = new ArrayList<DiskAddress> (); dafs.setSectors (blocks);
blocks.add (da); DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
int level = 1; node.setAllowsChildren (false);
headerNode.add (node);
}
StringBuilder list = new StringBuilder ("Level " + level + ":\n"); private void linkPictures (String title, DiskAddress da,
byte[] buffer = owner.getDisk ().readSector (da); DefaultMutableTreeNode headerNode)
String text = HexFormatter.getString (buffer, 0, 512); {
String[] spells = text.split ("\n"); List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
for (String s : spells) blocks.add (da);
{
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); byte[] buffer = owner.getDisk ().readSector (da);
dafs.setSectors (blocks); String text = printChars (buffer, 0);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
node.setAllowsChildren (false);
headerNode.add (node);
}
private String printChars (byte[] buffer, int block) DefaultAppleFileSource dafs = new DefaultAppleFileSource (title, text, owner);
{ dafs.setSectors (blocks);
StringBuilder text = new StringBuilder (); DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
for (int i = block * 512; i < (block + 1) * 512; i += 64) node.setAllowsChildren (false);
{ headerNode.add (node);
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 private void linkSpells (String title, DiskAddress da,
class ScenarioData DefaultMutableTreeNode headerNode)
{ {
int dunno; List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
int total; blocks.add (da);
int totalBlocks; int level = 1;
int dataOffset;
int type;
List<DiskAddress> sectors;
public ScenarioData (byte[] buffer, int seq, List<DiskAddress> sectors) StringBuilder list = new StringBuilder ("Level " + level + ":\n");
{ byte[] buffer = owner.getDisk ().readSector (da);
int offset = 42 + seq * 2; String text = HexFormatter.getString (buffer, 0, 512);
dunno = HexFormatter.intValue (buffer[offset]); String[] spells = text.split ("\n");
total = HexFormatter.intValue (buffer[offset + 16]); for (String s : spells)
totalBlocks = HexFormatter.intValue (buffer[offset + 32]); {
dataOffset = HexFormatter.intValue (buffer[offset + 48]); if (s.length () == 0)
type = seq; break;
if (s.startsWith ("*"))
{
s = s.substring (1);
level++;
list.append ("\nLevel " + level + ":\n");
}
list.append (" " + s + "\n");
}
this.sectors = new ArrayList<DiskAddress> (totalBlocks); DefaultAppleFileSource dafs =
for (int i = dataOffset, max = dataOffset + totalBlocks; i < max; i++) new DefaultAppleFileSource (title, list.toString (), owner);
this.sectors.add (sectors.get (i)); dafs.setSectors (blocks);
} DefaultMutableTreeNode node = new DefaultMutableTreeNode (dafs);
node.setAllowsChildren (false);
headerNode.add (node);
}
@Override private String printChars (byte[] buffer, int block)
public String toString () {
{ StringBuilder text = new StringBuilder ();
return String.format ("%-15s %3d %3d %3d %3d", typeText[type], dataOffset, for (int i = block * 512; i < (block + 1) * 512; i += 64)
totalBlocks, total, dunno); {
} 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++)
if (i < sectors.size ())
this.sectors.add (sectors.get (i));
}
@Override
public String toString ()
{
return String.format ("%-15s %3d %3d %3d %3d", typeText[type], dataOffset,
totalBlocks, total, dunno);
}
}
} }

View File

@ -0,0 +1,69 @@
package com.bytezone.diskbrowser.wizardry;
public class Huffman
{
private final byte[] tree;
private final byte[] left;
private final byte[] right;
private int bit = 0;
private int msgPtr = 0;
private int b = 0;
private byte[] message;
public Huffman (byte[] buffer)
{
tree = new byte[256];
left = new byte[256];
right = new byte[256];
System.arraycopy (buffer, 0, tree, 0, 256);
System.arraycopy (buffer, 256, left, 0, 256);
System.arraycopy (buffer, 512, right, 0, 256);
}
public String getMessage (byte[] message)
{
this.message = message;
bit = 0;
msgPtr = 0;
b = 0;
int len = getChar ();
StringBuilder text = new StringBuilder ();
for (int i = 0; i < len; i++)
text.append ((char) getChar ());
return text.toString ();
}
private byte getChar ()
{
int treePtr = 0;
while (true)
{
if (bit == 0)
{
bit = 8;
b = message[msgPtr++] & 0xFF;
}
int thisBit = b % 2;
b /= 2;
bit--;
if (thisBit == 0) // take right path
{
if ((tree[treePtr] & 0x02) != 0) // if has right leaf
return right[treePtr];
treePtr = right[treePtr]; // go to right node
}
else // take left path
{
if ((tree[treePtr] & 0x01) != 0) // if has left leaf
return left[treePtr];
treePtr = left[treePtr]; // go to left node
}
}
}
}

View File

@ -0,0 +1,58 @@
package com.bytezone.diskbrowser.wizardry;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.common.Utility;
public class MessageBlock
{
private final byte[] buffer;
private final int indexOffset;
private final int indexLength;
private final List<MessageDataBlock> messageDataBlocks =
new ArrayList<MessageDataBlock> ();
public MessageBlock (byte[] buffer)
{
this.buffer = buffer;
indexOffset = Utility.getWord (buffer, 0);
indexLength = Utility.getWord (buffer, 2);
int ptr = indexOffset * 512;
for (int i = 0, max = indexLength / 2; i < max; i++)
{
int firstMessageNo = Utility.getWord (buffer, ptr + i * 2);
MessageDataBlock messageDataBlock =
new MessageDataBlock (buffer, i * 512, firstMessageNo);
messageDataBlocks.add (messageDataBlock);
}
}
public byte[] getMessage (int messageNo)
{
for (int i = 0; i < messageDataBlocks.size (); i++)
{
MessageDataBlock messageDataBlock = messageDataBlocks.get (i);
if (messageDataBlock.firstMessageNo > messageNo)
return messageDataBlocks.get (i - 1).getMessage (messageNo);
}
return null;
}
// public int getBlock (int msgNo)
// {
// int ptr = indexOffset * 512;
//
// for (int i = 0; i < indexLength; i += 2)
// {
// int msg = Utility.getWord (buffer, ptr + i);
// if (msg > msgNo)
// return i - 1;
// }
// return indexLength - 1;
// }
}

View File

@ -0,0 +1,130 @@
package com.bytezone.diskbrowser.wizardry;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.common.Utility;
import com.bytezone.diskbrowser.utilities.HexFormatter;
public class MessageDataBlock
{
private final byte[] buffer;
private final int offset;
final int firstMessageNo;
private final int groupCount;
private final List<Message> messages = new ArrayList<Message> ();
public MessageDataBlock (byte[] buffer, int offset, int firstMessageNo)
{
this.buffer = buffer;
this.offset = offset;
this.firstMessageNo = firstMessageNo;
boolean debug = firstMessageNo == 0;
if (debug)
{
System.out.println (HexFormatter.format (buffer, offset, 512));
System.out.println ();
}
int ptr = offset + 0x1FF; // last byte in block
groupCount = buffer[ptr--] & 0xFF;
int currentMessageNo = firstMessageNo;
int totalMessageBytes = 0;
for (int i = 0, max = groupCount - 1; i < groupCount; i++, max--)
{
int huffBytes = buffer[ptr];
for (int j = 0; j < huffBytes; j++)
{
int messageLength = buffer[ptr - j - 1] & 0xFF;
totalMessageBytes += messageLength;
Message message = new Message (currentMessageNo + j,
offset + totalMessageBytes - messageLength, messageLength);
messages.add (message);
}
ptr -= huffBytes;
currentMessageNo += huffBytes;
ptr--;
if (max > 0)
{
byte gap = buffer[ptr--];
int skip = gap & 0xFF;
if ((gap & 0x80) != 0) // is high bit set?
{
gap &= 0x7F;
int gap2 = buffer[ptr--] & 0xFF;
skip = gap * 256 + gap2;
}
skip--;
currentMessageNo += skip;
}
}
if (debug)
System.out.println (this);
}
byte[] getMessage (int messageNo)
{
for (Message message : messages)
if (message.msgNo == messageNo)
{
byte[] returnMessage = new byte[message.length];
System.arraycopy (buffer, message.offset, returnMessage, 0, message.length);
return returnMessage;
}
return null;
}
@Override
public String toString ()
{
StringBuilder text = new StringBuilder ();
for (Message message : messages)
{
text.append (message);
text.append ("\n");
}
if (text.length () > 0)
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
class Message
{
final int msgNo;
final int offset;
final int length;
public Message (int msgNo, int offset, int length)
{
this.msgNo = msgNo;
this.offset = offset;
this.length = length;
}
@Override
public String toString ()
{
StringBuilder text = new StringBuilder ();
String data = Utility.getHex (buffer, offset, length);
text.append (String.format ("%5d: %02X %02X : %s", msgNo, offset, length, data));
return text.toString ();
}
}
}

View File

@ -11,16 +11,18 @@ import com.bytezone.diskbrowser.disk.AppleDisk;
import com.bytezone.diskbrowser.disk.DefaultAppleFileSource; import com.bytezone.diskbrowser.disk.DefaultAppleFileSource;
import com.bytezone.diskbrowser.disk.Disk; import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress; import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.SectorType;
import com.bytezone.diskbrowser.pascal.FileEntry; import com.bytezone.diskbrowser.pascal.FileEntry;
import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.utilities.Utility; import com.bytezone.diskbrowser.utilities.Utility;
import com.bytezone.diskbrowser.wizardry.Header.ScenarioData;
public class Wizardry4BootDisk extends PascalDisk public class Wizardry4BootDisk extends PascalDisk
{ {
public Header scenarioHeader;
List<AppleDisk> disks = new ArrayList<AppleDisk> (); List<AppleDisk> disks = new ArrayList<AppleDisk> ();
// protected Disk[] dataDisks; // protected Disk[] dataDisks;
private Relocator relocator; private Relocator relocator;
private MessageBlock messageBlock;
public Wizardry4BootDisk (AppleDisk[] dataDisks) public Wizardry4BootDisk (AppleDisk[] dataDisks)
{ {
@ -34,7 +36,6 @@ public class Wizardry4BootDisk extends PascalDisk
// get the relocation table // get the relocation table
DefaultMutableTreeNode relocNode = findNode (currentRoot, "SYSTEM.RELOC"); DefaultMutableTreeNode relocNode = findNode (currentRoot, "SYSTEM.RELOC");
FileEntry fileEntry = (FileEntry) relocNode.getUserObject (); FileEntry fileEntry = (FileEntry) relocNode.getUserObject ();
if (fileEntry != null) if (fileEntry != null)
{ {
relocator = relocator =
@ -46,7 +47,6 @@ public class Wizardry4BootDisk extends PascalDisk
// reset the code segment so that it rebuilds itself from the new data // reset the code segment so that it rebuilds itself from the new data
DefaultMutableTreeNode pascalNode = findNode (currentRoot, "SYSTEM.PASCAL"); DefaultMutableTreeNode pascalNode = findNode (currentRoot, "SYSTEM.PASCAL");
fileEntry = (FileEntry) pascalNode.getUserObject (); fileEntry = (FileEntry) pascalNode.getUserObject ();
if (fileEntry != null) if (fileEntry != null)
{ {
fileEntry.setFile (null); fileEntry.setFile (null);
@ -55,54 +55,99 @@ public class Wizardry4BootDisk extends PascalDisk
DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA"); DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA");
fileEntry = (FileEntry) scenarioNode.getUserObject (); fileEntry = (FileEntry) scenarioNode.getUserObject ();
if (fileEntry != null) if (fileEntry != null)
{ {
fileEntry.setFile (null); fileEntry.setFile (null);
scenarioNode.setAllowsChildren (true); scenarioNode.setAllowsChildren (true);
scenarioHeader = new Header (scenarioNode, this);
byte[] buffer = fileEntry.getDataSource ().buffer; linkMazeLevels (scenarioNode, fileEntry);
for (int i = 0; i < 14; i++)
{
byte[] level = new byte[896];
// System.out.println (HexFormatter.format (buffer, 0, 512));
System.arraycopy (buffer, 0xC600 + i * 1024, level, 0, level.length);
MazeLevel maze = new MazeLevel (level, i);
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
addToNode (maze, scenarioNode, blocks, null);
}
} }
DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS"); DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS");
fileEntry = (FileEntry) monstersNode.getUserObject (); fileEntry = (FileEntry) monstersNode.getUserObject ();
if (fileEntry != null) if (fileEntry != null)
{ {
monstersNode.setAllowsChildren (true); fileEntry.setFile (null);
byte[] pictureBuffer = fileEntry.getDataSource ().buffer;
List<DiskAddress> pictureBlocks = fileEntry.getSectors ();
int count = 0; monstersNode.setAllowsChildren (true);
loop: for (int block = 0; block < 24; block++) linkMonsterImages (monstersNode, fileEntry);
}
DefaultMutableTreeNode messagesNode = findNode (currentRoot, "ASCII.KRN");
fileEntry = (FileEntry) messagesNode.getUserObject ();
if (fileEntry != null)
{
messageBlock = new MessageBlock (fileEntry.getDataSource ().buffer);
}
DefaultMutableTreeNode huffNode = findNode (currentRoot, "ASCII.HUFF");
fileEntry = (FileEntry) huffNode.getUserObject ();
if (fileEntry != null)
{
// byte[] tree = new byte[256];
// byte[] left = new byte[256];
// byte[] right = new byte[256];
byte[] buffer = fileEntry.getDataSource ().buffer;
// System.arraycopy (buffer, 0, tree, 0, 256);
// System.arraycopy (buffer, 256, left, 0, 256);
// System.arraycopy (buffer, 512, right, 0, 256);
Huffman huffman = new Huffman (buffer);
System.out.println (huffman.getMessage (messageBlock.getMessage (2043)));
System.out.println (huffman.getMessage (messageBlock.getMessage (2044)));
System.out.println (huffman.getMessage (messageBlock.getMessage (2045)));
}
}
private void linkMazeLevels (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
{
ScenarioData mazeData = scenarioHeader.data.get (Header.MAZE_AREA);
byte[] buffer = fileEntry.getDataSource ().buffer;
List<DiskAddress> blocks = fileEntry.getSectors ();
DefaultMutableTreeNode mazeNode = linkNode ("Maze", "Levels string", scenarioNode);
for (int i = 0; i < 15; i++)
{
byte[] level = new byte[896];
System.arraycopy (buffer, mazeData.dataOffset * 512 + i * 1024, level, 0,
level.length);
List<DiskAddress> mazeBlocks = new ArrayList<DiskAddress> ();
int ptr = mazeData.dataOffset + i * 2;
mazeBlocks.add (blocks.get (ptr));
mazeBlocks.add (blocks.get (ptr + 1));
addToNode (new MazeLevel (level, i), mazeNode, mazeBlocks);
}
}
private void linkMonsterImages (DefaultMutableTreeNode monstersNode,
FileEntry fileEntry)
{
byte[] pictureBuffer = fileEntry.getDataSource ().buffer;
List<DiskAddress> pictureBlocks = fileEntry.getSectors ();
int count = 0;
for (int block = 0; block < 24; block++)
{
int ptr = block * 512;
for (int pic = 0; pic < 2; pic++)
{ {
int ptr = block * 512; byte[] buffer = new byte[240];
for (int pic = 0; pic < 2; pic++) System.arraycopy (pictureBuffer, ptr + pic * 256, buffer, 0, 240);
{ Wiz4Image image = new Wiz4Image ("Image " + count++, buffer);
byte[] buffer = new byte[240]; List<DiskAddress> monsterBlocks = new ArrayList<DiskAddress> ();
System.arraycopy (pictureBuffer, ptr + pic * 256, buffer, 0, 240); monsterBlocks.add (pictureBlocks.get (block));
Wiz4Image image = new Wiz4Image ("Image " + count++, buffer); addToNode (image, monstersNode, monsterBlocks);
List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
blocks.add (pictureBlocks.get (block));
addToNode (image, monstersNode, blocks, null);
}
} }
} }
} }
private void addToNode (AbstractFile af, DefaultMutableTreeNode node, private void addToNode (AbstractFile af, DefaultMutableTreeNode node,
List<DiskAddress> blocks, SectorType type) List<DiskAddress> blocks)
{ {
DefaultAppleFileSource dafs = DefaultAppleFileSource dafs =
new DefaultAppleFileSource (af.getName (), af, this, blocks); new DefaultAppleFileSource (af.getName (), af, this, blocks);
@ -111,6 +156,15 @@ public class Wizardry4BootDisk extends PascalDisk
childNode.setAllowsChildren (false); childNode.setAllowsChildren (false);
} }
private DefaultMutableTreeNode linkNode (String name, String text,
DefaultMutableTreeNode parent)
{
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
parent.add (node);
return node;
}
public static boolean isWizardryIVorV (Disk disk, boolean debug) public static boolean isWizardryIVorV (Disk disk, boolean debug)
{ {
// Wizardry IV or V boot code // Wizardry IV or V boot code

View File

@ -488,12 +488,12 @@ public class WizardryScenarioDisk extends PascalDisk
System.arraycopy (buffer, 0, data2, 0, data2.length); System.arraycopy (buffer, 0, data2, 0, data2.length);
// System.out.println (HexFormatter.format (data2)); // System.out.println (HexFormatter.format (data2));
MazeLevel model = new MazeLevel (data2, i + 1); MazeLevel mazeLevel = new MazeLevel (data2, i + 1);
model.setMessages (messages); mazeLevel.setMessages (messages);
model.setMonsters (monsters); mazeLevel.setMonsters (monsters);
model.setItems (items); mazeLevel.setItems (items);
levels.add (model); levels.add (mazeLevel);
addToNode (model, node, blocks, mazeSector); addToNode (mazeLevel, node, blocks, mazeSector);
} }
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();