2016-08-22 03:41:43 +00:00
|
|
|
package com.bytezone.diskbrowser.wizardry;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2016-09-19 09:09:41 +00:00
|
|
|
import java.util.Iterator;
|
2016-08-22 03:41:43 +00:00
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import com.bytezone.common.Utility;
|
|
|
|
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
|
|
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
public class Wiz5Monsters extends AbstractFile implements Iterable<Wiz5Monsters.Monster>
|
2016-08-22 03:41:43 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
private static final int BLOCK_SIZE = 512;
|
|
|
|
private final List<Monster> monsters = new ArrayList<Monster> ();
|
2016-08-22 03:41:43 +00:00
|
|
|
|
|
|
|
public Wiz5Monsters (String name, byte[] buffer)
|
|
|
|
{
|
|
|
|
super (name, buffer);
|
|
|
|
|
2016-09-19 05:18:10 +00:00
|
|
|
int p = 0;
|
2016-09-19 09:09:41 +00:00
|
|
|
int nextBlock = buffer[p] & 0xFF;
|
2016-09-19 05:18:10 +00:00
|
|
|
int nextOffset = Utility.getWord (buffer, 256);
|
2016-09-19 09:09:41 +00:00
|
|
|
|
|
|
|
Monster monster = new Monster (p + 1);
|
2016-09-19 05:18:10 +00:00
|
|
|
monsters.add (monster);
|
|
|
|
boolean createMonster = false;
|
|
|
|
|
|
|
|
while (nextBlock > 0)
|
2016-08-22 03:41:43 +00:00
|
|
|
{
|
2016-09-19 05:18:10 +00:00
|
|
|
int firstBlock = nextBlock;
|
|
|
|
int firstOffset = nextOffset;
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
int ndx = nextBlock * BLOCK_SIZE + nextOffset;
|
2016-09-19 05:18:10 +00:00
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
if (buffer[ndx] != (byte) 0)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
nextBlock = buffer[ndx] & 0xFF;
|
|
|
|
nextOffset = Utility.getWord (buffer, ndx + 1);
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
nextBlock = buffer[++p] & 0xFF;
|
|
|
|
nextOffset = Utility.getWord (buffer, p * 2 + 256);
|
|
|
|
createMonster = true;
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
int length = nextOffset > 0 ? nextOffset : BLOCK_SIZE - firstOffset;
|
|
|
|
monster.dataBuffers.add (new DataBuffer (firstBlock, firstOffset, length));
|
2016-09-19 05:18:10 +00:00
|
|
|
|
|
|
|
if (createMonster && nextBlock > 0)
|
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
monster = new Monster (p + 1);
|
2016-09-19 05:18:10 +00:00
|
|
|
monsters.add (monster);
|
2016-09-19 09:09:41 +00:00
|
|
|
createMonster = false;
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
2016-08-22 03:41:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
@Override
|
|
|
|
public Iterator<Monster> iterator ()
|
|
|
|
{
|
|
|
|
return monsters.iterator ();
|
|
|
|
}
|
|
|
|
|
2016-08-22 03:41:43 +00:00
|
|
|
@Override
|
|
|
|
public String getText ()
|
|
|
|
{
|
|
|
|
StringBuilder text = new StringBuilder ();
|
|
|
|
|
2016-09-18 10:06:26 +00:00
|
|
|
for (Monster monster : monsters)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
DataBuffer dataBuffer = monster.dataBuffers.get (0);
|
|
|
|
text.append (String.format ("%02X : %02X %04X : %s%n", monster.id, dataBuffer.block,
|
|
|
|
dataBuffer.offset, dataBuffer.toHexString ()));
|
|
|
|
for (int i = 1; i < monster.dataBuffers.size (); i++)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
dataBuffer = monster.dataBuffers.get (i);
|
2016-09-22 04:42:55 +00:00
|
|
|
text.append (String.format (" %02X %04X : %s%n", dataBuffer.block,
|
|
|
|
dataBuffer.offset, dataBuffer.toHexString ()));
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
2016-09-22 04:42:55 +00:00
|
|
|
text.append ("\n");
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
2016-09-18 10:06:26 +00:00
|
|
|
|
2016-09-22 04:42:55 +00:00
|
|
|
if (text.length () > 1)
|
|
|
|
{
|
|
|
|
text.deleteCharAt (text.length () - 1);
|
2016-09-18 10:06:26 +00:00
|
|
|
text.deleteCharAt (text.length () - 1);
|
2016-09-22 04:42:55 +00:00
|
|
|
}
|
2016-09-18 10:06:26 +00:00
|
|
|
|
2016-08-22 03:41:43 +00:00
|
|
|
return text.toString ();
|
|
|
|
}
|
2016-09-18 10:06:26 +00:00
|
|
|
|
|
|
|
class Monster
|
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
private final int id;
|
|
|
|
private final List<DataBuffer> dataBuffers = new ArrayList<DataBuffer> ();
|
2016-09-19 05:18:10 +00:00
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
private Wiz4Image image;
|
|
|
|
private byte[] data;
|
2016-09-19 05:18:10 +00:00
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
public Monster (int id)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
|
|
|
this.id = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Wiz4Image getImage ()
|
|
|
|
{
|
|
|
|
if (image == null)
|
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
int length = 0;
|
|
|
|
for (DataBuffer dataBuffer : dataBuffers)
|
|
|
|
length += dataBuffer.length - 3;
|
2016-09-19 05:18:10 +00:00
|
|
|
|
|
|
|
data = new byte[length];
|
|
|
|
|
|
|
|
int ptr = 0;
|
2016-09-19 09:09:41 +00:00
|
|
|
for (DataBuffer dataBuffer : dataBuffers)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
int offset = dataBuffer.block * BLOCK_SIZE + dataBuffer.offset + 3;
|
|
|
|
System.arraycopy (buffer, offset, data, ptr, dataBuffer.length - 3);
|
|
|
|
ptr += dataBuffer.length - 3;
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
2016-09-22 04:42:55 +00:00
|
|
|
image = new Wiz4Image ("Image " + id, data, 10, 6);
|
|
|
|
// System.out.printf ("Monster# %d%n", id);
|
|
|
|
// System.out.println (Utility.toHex (data));
|
|
|
|
// System.out.println ();
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2016-09-19 10:37:50 +00:00
|
|
|
List<Integer> getBlocks ()
|
|
|
|
{
|
|
|
|
List<Integer> blocks = new ArrayList<Integer> ();
|
|
|
|
for (DataBuffer dataBuffer : dataBuffers)
|
|
|
|
blocks.add (dataBuffer.block);
|
|
|
|
return blocks;
|
|
|
|
}
|
|
|
|
|
2016-09-19 05:18:10 +00:00
|
|
|
@Override
|
|
|
|
public String toString ()
|
|
|
|
{
|
|
|
|
StringBuilder text = new StringBuilder ();
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
for (DataBuffer dataBuffer : dataBuffers)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
text.append (dataBuffer);
|
2016-09-19 05:18:10 +00:00
|
|
|
text.append ("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return text.toString ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
class DataBuffer
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
private final int block;
|
|
|
|
private final int offset;
|
|
|
|
private final int length;
|
2016-09-19 05:18:10 +00:00
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
public DataBuffer (int block, int offset, int length)
|
2016-09-19 05:18:10 +00:00
|
|
|
{
|
|
|
|
this.block = block;
|
|
|
|
this.offset = offset;
|
|
|
|
this.length = length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toHexString ()
|
|
|
|
{
|
2016-09-22 04:42:55 +00:00
|
|
|
int p1 = block * BLOCK_SIZE + offset;
|
|
|
|
String s1 = HexFormatter.getHexString (buffer, p1, 3);
|
|
|
|
String s2 = HexFormatter.getHexString (buffer, p1 + 3, length - 3);
|
|
|
|
// split (p1 + 3, length - 3);
|
|
|
|
return s1 + " : " + s2;
|
|
|
|
}
|
|
|
|
|
2018-04-25 20:41:03 +00:00
|
|
|
// private void split (int offset, int length)
|
|
|
|
// {
|
|
|
|
// for (int p = offset; length > 0; p += 16, length -= 16)
|
|
|
|
// {
|
|
|
|
// int len = length > 15 ? 16 : length;
|
|
|
|
// String s = HexFormatter.getHexString (buffer, p, len);
|
|
|
|
// System.out.println (s);
|
|
|
|
// }
|
|
|
|
// System.out.println ();
|
|
|
|
// }
|
2016-09-19 05:18:10 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString ()
|
|
|
|
{
|
2016-09-19 09:09:41 +00:00
|
|
|
return (HexFormatter.format (buffer, block * BLOCK_SIZE + offset, length));
|
2016-09-19 05:18:10 +00:00
|
|
|
}
|
2016-09-18 10:06:26 +00:00
|
|
|
}
|
2016-08-22 03:41:43 +00:00
|
|
|
}
|