2016-08-08 04:53:29 +00:00
|
|
|
package com.bytezone.diskbrowser.wizardry;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2016-08-09 04:15:44 +00:00
|
|
|
import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
|
import javax.swing.tree.DefaultTreeModel;
|
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
2016-08-08 04:53:29 +00:00
|
|
|
import com.bytezone.diskbrowser.disk.AppleDisk;
|
2016-08-14 08:41:19 +00:00
|
|
|
import com.bytezone.diskbrowser.disk.DefaultAppleFileSource;
|
2016-08-08 04:53:29 +00:00
|
|
|
import com.bytezone.diskbrowser.disk.Disk;
|
2016-08-14 08:41:19 +00:00
|
|
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
2016-08-09 04:15:44 +00:00
|
|
|
import com.bytezone.diskbrowser.pascal.FileEntry;
|
2016-08-08 04:53:29 +00:00
|
|
|
import com.bytezone.diskbrowser.pascal.PascalDisk;
|
2016-09-01 04:01:47 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
2016-08-08 04:53:29 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.Utility;
|
2016-08-16 06:34:23 +00:00
|
|
|
import com.bytezone.diskbrowser.wizardry.Header.ScenarioData;
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2016-08-08 04:53:29 +00:00
|
|
|
public class Wizardry4BootDisk extends PascalDisk
|
2020-02-11 07:29:55 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2016-08-08 04:53:29 +00:00
|
|
|
{
|
2016-08-16 06:34:23 +00:00
|
|
|
public Header scenarioHeader;
|
2016-08-09 04:15:44 +00:00
|
|
|
private Relocator relocator;
|
2016-08-16 06:34:23 +00:00
|
|
|
private MessageBlock messageBlock;
|
2016-08-18 06:35:54 +00:00
|
|
|
private Huffman huffman;
|
2016-08-19 09:57:29 +00:00
|
|
|
private final int version;
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2022-05-28 08:54:06 +00:00
|
|
|
private List<CharacterV4> characters = new ArrayList<> ();
|
2022-05-29 00:43:10 +00:00
|
|
|
private List<CharacterParty> parties = new ArrayList<> ();
|
2022-05-28 08:54:06 +00:00
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-08 04:53:29 +00:00
|
|
|
public Wizardry4BootDisk (AppleDisk[] dataDisks)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-08 04:53:29 +00:00
|
|
|
{
|
2016-08-09 04:15:44 +00:00
|
|
|
super (dataDisks[0]);
|
|
|
|
|
2022-05-27 08:30:30 +00:00
|
|
|
version = dataDisks.length == 7 ? 4 : dataDisks.length == 10 ? 5 : 0;
|
2016-08-09 04:15:44 +00:00
|
|
|
|
|
|
|
DefaultTreeModel model = (DefaultTreeModel) catalogTree.getModel ();
|
|
|
|
DefaultMutableTreeNode currentRoot = (DefaultMutableTreeNode) model.getRoot ();
|
2016-08-14 08:41:19 +00:00
|
|
|
|
|
|
|
// get the relocation table
|
2016-08-09 04:15:44 +00:00
|
|
|
DefaultMutableTreeNode relocNode = findNode (currentRoot, "SYSTEM.RELOC");
|
|
|
|
FileEntry fileEntry = (FileEntry) relocNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
2022-05-03 05:36:37 +00:00
|
|
|
relocator = new Relocator (fileEntry.getUniqueName (), fileEntry.getDataSource ().buffer);
|
|
|
|
relocator.createNewBuffer (dataDisks);
|
2016-08-09 04:15:44 +00:00
|
|
|
fileEntry.setFile (relocator);
|
|
|
|
}
|
2016-08-09 09:09:11 +00:00
|
|
|
|
|
|
|
// reset the code segment so that it rebuilds itself from the new data
|
|
|
|
DefaultMutableTreeNode pascalNode = findNode (currentRoot, "SYSTEM.PASCAL");
|
|
|
|
fileEntry = (FileEntry) pascalNode.getUserObject ();
|
2016-08-14 08:41:19 +00:00
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
2016-08-14 08:50:41 +00:00
|
|
|
fileEntry.setFile (null);
|
|
|
|
fileEntry.getDataSource ();
|
2016-08-14 08:41:19 +00:00
|
|
|
}
|
|
|
|
|
2016-08-23 14:14:04 +00:00
|
|
|
DefaultMutableTreeNode huffNode = findNode (currentRoot, "ASCII.HUFF");
|
|
|
|
fileEntry = (FileEntry) huffNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
2022-05-03 05:36:37 +00:00
|
|
|
huffman = new Huffman ("Huffman tree", fileEntry.getDataSource ().buffer);
|
2016-08-23 14:14:04 +00:00
|
|
|
fileEntry.setFile (huffman);
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultMutableTreeNode messagesNode = findNode (currentRoot, "ASCII.KRN");
|
|
|
|
fileEntry = (FileEntry) messagesNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
|
|
|
messageBlock = new MessageBlock (fileEntry.getDataSource ().buffer, huffman);
|
|
|
|
fileEntry.setFile (messageBlock);
|
|
|
|
messagesNode.setAllowsChildren (true);
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
for (MessageDataBlock mdb : messageBlock)
|
|
|
|
{
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> messageBlocks = new ArrayList<> ();
|
2016-08-23 14:14:04 +00:00
|
|
|
messageBlocks.add (blocks.get (count++));
|
|
|
|
addToNode (mdb, messagesNode, messageBlocks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-27 08:30:30 +00:00
|
|
|
// scenario data
|
2016-08-19 09:57:29 +00:00
|
|
|
if (version == 4)
|
2016-08-14 08:41:19 +00:00
|
|
|
{
|
2016-08-19 09:57:29 +00:00
|
|
|
DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA");
|
2016-08-22 03:41:43 +00:00
|
|
|
fileEntry = (FileEntry) scenarioNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
2016-08-19 09:57:29 +00:00
|
|
|
{
|
2016-08-22 03:41:43 +00:00
|
|
|
fileEntry.setFile (null);
|
|
|
|
scenarioNode.setAllowsChildren (true);
|
|
|
|
scenarioHeader = new Header (scenarioNode, this);
|
2022-05-27 08:30:30 +00:00
|
|
|
linkCharacters4 (scenarioNode, fileEntry);
|
2022-05-29 00:43:10 +00:00
|
|
|
linkParties ();
|
2016-08-22 03:41:43 +00:00
|
|
|
linkMazeLevels4 (scenarioNode, fileEntry);
|
2022-05-28 02:59:25 +00:00
|
|
|
linkMonstersV4 (scenarioNode, fileEntry);
|
|
|
|
linkItemsV4 (scenarioNode, fileEntry);
|
2016-08-19 09:57:29 +00:00
|
|
|
}
|
2016-08-16 06:34:23 +00:00
|
|
|
}
|
2016-08-19 09:57:29 +00:00
|
|
|
else if (version == 5)
|
2016-08-16 06:34:23 +00:00
|
|
|
{
|
2016-08-19 09:57:29 +00:00
|
|
|
DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "DRAGON.DATA");
|
2016-08-22 03:41:43 +00:00
|
|
|
fileEntry = (FileEntry) scenarioNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
|
|
|
fileEntry.setFile (null);
|
|
|
|
scenarioNode.setAllowsChildren (true);
|
|
|
|
linkMazeLevels5 (scenarioNode, fileEntry);
|
2016-09-01 04:01:47 +00:00
|
|
|
linkBlock1 (scenarioNode, fileEntry);
|
|
|
|
linkOracle (scenarioNode, fileEntry);
|
|
|
|
linkBlock2 (scenarioNode, fileEntry);
|
2016-08-22 03:41:43 +00:00
|
|
|
}
|
2016-08-19 09:57:29 +00:00
|
|
|
}
|
2022-05-27 08:30:30 +00:00
|
|
|
else
|
|
|
|
System.out.println ("No Wizardry version set");
|
2016-08-16 06:34:23 +00:00
|
|
|
|
2022-05-27 08:30:30 +00:00
|
|
|
// monster images
|
2016-08-19 09:57:29 +00:00
|
|
|
if (version == 4)
|
|
|
|
{
|
|
|
|
DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS");
|
|
|
|
fileEntry = (FileEntry) monstersNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
|
|
|
monstersNode.setAllowsChildren (true);
|
|
|
|
linkMonsterImages4 (monstersNode, fileEntry);
|
|
|
|
}
|
2016-08-16 06:34:23 +00:00
|
|
|
}
|
2016-08-22 03:41:43 +00:00
|
|
|
else if (version == 5)
|
|
|
|
{
|
|
|
|
DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS");
|
|
|
|
fileEntry = (FileEntry) monstersNode.getUserObject ();
|
|
|
|
if (fileEntry != null)
|
|
|
|
{
|
|
|
|
monstersNode.setAllowsChildren (true);
|
2016-09-18 10:06:26 +00:00
|
|
|
linkMonsterImages5 (monstersNode, fileEntry);
|
2016-08-22 03:41:43 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-16 06:34:23 +00:00
|
|
|
}
|
2016-08-14 08:41:19 +00:00
|
|
|
|
2022-05-27 08:30:30 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void linkCharacters4 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
ScenarioData sd = scenarioHeader.get (Header.CHARACTER_AREA);
|
|
|
|
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
DefaultMutableTreeNode charactersNode = linkNode ("Characters", "Characters", scenarioNode);
|
|
|
|
List<DiskAddress> allCharacterBlocks = new ArrayList<> ();
|
|
|
|
|
|
|
|
int ptr = sd.dataOffset * 512;
|
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++)
|
|
|
|
{
|
|
|
|
byte[] out = huffman.decodeMessage (buffer, ptr, sd.totalBlocks);
|
|
|
|
|
|
|
|
String name = HexFormatter.getPascalString (out, 1);
|
|
|
|
|
2022-05-28 08:54:06 +00:00
|
|
|
CharacterV4 c = new CharacterV4 (name, out, i);
|
|
|
|
characters.add (c);
|
|
|
|
|
2022-05-29 00:43:10 +00:00
|
|
|
if (!name.isEmpty ())
|
|
|
|
{
|
|
|
|
List<DiskAddress> characterBlocks = new ArrayList<> ();
|
|
|
|
DiskAddress da = blocks.get (ptr / 512);
|
|
|
|
characterBlocks.add (da);
|
|
|
|
addToNode (c, charactersNode, characterBlocks);
|
2022-05-27 08:30:30 +00:00
|
|
|
|
2022-05-29 00:43:10 +00:00
|
|
|
if (!allCharacterBlocks.contains (da))
|
|
|
|
allCharacterBlocks.add (da);
|
|
|
|
}
|
2022-05-27 08:30:30 +00:00
|
|
|
|
|
|
|
ptr += sd.totalBlocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) charactersNode.getUserObject ();
|
|
|
|
afs.setSectors (allCharacterBlocks);
|
2022-05-29 00:43:10 +00:00
|
|
|
}
|
2022-05-28 08:54:06 +00:00
|
|
|
|
2022-05-29 00:43:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void linkParties ()
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
2022-05-28 08:54:06 +00:00
|
|
|
for (CharacterV4 character : characters)
|
2022-05-29 00:43:10 +00:00
|
|
|
{
|
|
|
|
if (character.isInParty () || character.getName ().isEmpty ())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
CharacterParty party = new CharacterParty ();
|
|
|
|
parties.add (party);
|
|
|
|
link (character, party);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void link (CharacterV4 character, CharacterParty party)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
if (character.isInParty ())
|
|
|
|
return;
|
|
|
|
|
|
|
|
party.add (character);
|
|
|
|
|
|
|
|
if (character.nextCharacterId > 0)
|
|
|
|
link (characters.get (character.nextCharacterId), party);
|
2022-05-27 08:30:30 +00:00
|
|
|
}
|
|
|
|
|
2022-05-28 02:59:25 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void linkMonstersV4 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
ScenarioData sd = scenarioHeader.get (Header.MONSTER_AREA);
|
|
|
|
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
DefaultMutableTreeNode monstersNode = linkNode ("Monsters", "Monsters", scenarioNode);
|
|
|
|
List<DiskAddress> allMonsterBlocks = new ArrayList<> ();
|
|
|
|
|
|
|
|
String[] monsterNames = new String[4];
|
|
|
|
|
|
|
|
int ptr = sd.dataOffset * 512;
|
|
|
|
|
|
|
|
for (int i = 0; i < sd.total; i++)
|
|
|
|
{
|
|
|
|
byte[] out = huffman.decodeMessage (buffer, ptr, sd.totalBlocks);
|
|
|
|
|
2022-05-29 00:43:10 +00:00
|
|
|
for (int j = 0; j < monsterNames.length; j++)
|
2022-05-28 02:59:25 +00:00
|
|
|
monsterNames[j] = messageBlock.getMessageLine (i * 4 + 13000 + j);
|
|
|
|
|
|
|
|
MonsterV4 monster = new MonsterV4 (monsterNames, out, i);
|
|
|
|
|
|
|
|
List<DiskAddress> monsterBlocks = new ArrayList<> ();
|
|
|
|
DiskAddress da = blocks.get (ptr / 512);
|
|
|
|
monsterBlocks.add (da);
|
|
|
|
addToNode (monster, monstersNode, monsterBlocks);
|
|
|
|
|
|
|
|
if (!allMonsterBlocks.contains (da))
|
|
|
|
allMonsterBlocks.add (da);
|
|
|
|
|
|
|
|
ptr += sd.totalBlocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) monstersNode.getUserObject ();
|
|
|
|
afs.setSectors (allMonsterBlocks);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void linkItemsV4 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
ScenarioData sd = scenarioHeader.get (Header.ITEM_AREA);
|
|
|
|
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
DefaultMutableTreeNode itemsNode = linkNode ("Items", "Items", scenarioNode);
|
|
|
|
List<DiskAddress> allItemBlocks = new ArrayList<> ();
|
|
|
|
|
|
|
|
String[] itemNames = new String[2];
|
|
|
|
|
|
|
|
int ptr = sd.dataOffset * 512;
|
|
|
|
|
|
|
|
for (int i = 0; i < sd.total; i++)
|
|
|
|
{
|
|
|
|
byte[] out = huffman.decodeMessage (buffer, ptr, sd.totalBlocks);
|
|
|
|
|
2022-05-29 00:43:10 +00:00
|
|
|
for (int j = 0; j < itemNames.length; j++)
|
2022-05-28 02:59:25 +00:00
|
|
|
{
|
|
|
|
itemNames[j] = messageBlock.getMessageLine (i * 2 + 14000 + j);
|
|
|
|
if (itemNames[j] == null)
|
|
|
|
itemNames[j] = "Not found";
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemV4 item = new ItemV4 (itemNames, out, i);
|
|
|
|
|
|
|
|
List<DiskAddress> itemBlocks = new ArrayList<> ();
|
|
|
|
DiskAddress da = blocks.get (ptr / 512);
|
|
|
|
itemBlocks.add (da);
|
|
|
|
addToNode (item, itemsNode, itemBlocks);
|
|
|
|
|
|
|
|
if (!allItemBlocks.contains (da))
|
|
|
|
allItemBlocks.add (da);
|
|
|
|
|
|
|
|
ptr += sd.totalBlocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) itemsNode.getUserObject ();
|
|
|
|
afs.setSectors (allItemBlocks);
|
|
|
|
}
|
|
|
|
|
2022-05-27 08:30:30 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private void linkMazeLevels4 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
ScenarioData mazeData = scenarioHeader.get (Header.MAZE_AREA);
|
|
|
|
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
DefaultMutableTreeNode mazeNode = linkNode ("Maze", "Levels string", scenarioNode);
|
|
|
|
List<DiskAddress> allMazeBlocks = new ArrayList<> ();
|
|
|
|
|
|
|
|
for (int i = 0; i < mazeData.total; i++)
|
|
|
|
{
|
|
|
|
int blockPtr = mazeData.dataOffset + i * 2;
|
|
|
|
|
|
|
|
byte[] level = new byte[0x380]; // 896
|
|
|
|
System.arraycopy (buffer, blockPtr * 512, level, 0, level.length);
|
|
|
|
|
|
|
|
List<DiskAddress> mazeBlocks = new ArrayList<> ();
|
|
|
|
mazeBlocks.add (blocks.get (blockPtr));
|
|
|
|
mazeBlocks.add (blocks.get (blockPtr + 1));
|
|
|
|
addToNode (new MazeLevel (level, i), mazeNode, mazeBlocks);
|
|
|
|
allMazeBlocks.addAll (mazeBlocks);
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) mazeNode.getUserObject ();
|
|
|
|
afs.setSectors (allMazeBlocks);
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2022-05-03 05:36:37 +00:00
|
|
|
private void linkMonsterImages4 (DefaultMutableTreeNode monstersNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-18 10:06:26 +00:00
|
|
|
{
|
|
|
|
List<DiskAddress> pictureBlocks = fileEntry.getSectors ();
|
|
|
|
|
2022-05-03 05:36:37 +00:00
|
|
|
Wiz4Monsters w4monsters = new Wiz4Monsters ("monsters", fileEntry.getDataSource ().buffer);
|
2016-09-18 10:06:26 +00:00
|
|
|
fileEntry.setFile (w4monsters);
|
2016-09-19 10:37:50 +00:00
|
|
|
|
2016-09-18 10:06:26 +00:00
|
|
|
int count = 0;
|
|
|
|
for (Wiz4Image image : w4monsters.images)
|
|
|
|
{
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> monsterBlocks = new ArrayList<> ();
|
2016-09-18 10:06:26 +00:00
|
|
|
monsterBlocks.add (pictureBlocks.get (w4monsters.blocks.get (count++)));
|
|
|
|
addToNode (image, monstersNode, monsterBlocks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2022-05-03 05:36:37 +00:00
|
|
|
private void linkMonsterImages5 (DefaultMutableTreeNode monstersNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-18 10:06:26 +00:00
|
|
|
{
|
2016-09-19 10:37:50 +00:00
|
|
|
List<DiskAddress> pictureBlocks = fileEntry.getSectors ();
|
|
|
|
|
2022-05-03 05:36:37 +00:00
|
|
|
Wiz5Monsters w5monsters = new Wiz5Monsters ("monsters", fileEntry.getDataSource ().buffer);
|
2016-09-18 10:06:26 +00:00
|
|
|
fileEntry.setFile (w5monsters);
|
2016-09-19 10:37:50 +00:00
|
|
|
|
2016-09-19 09:09:41 +00:00
|
|
|
for (Wiz5Monsters.Monster monster : w5monsters)
|
2016-09-18 10:06:26 +00:00
|
|
|
{
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> monsterBlocks = new ArrayList<> ();
|
2016-09-19 10:37:50 +00:00
|
|
|
for (Integer blockId : monster.getBlocks ())
|
|
|
|
monsterBlocks.add (pictureBlocks.get (blockId));
|
2016-09-19 05:18:10 +00:00
|
|
|
addToNode (monster.getImage (), monstersNode, monsterBlocks);
|
2016-09-18 10:06:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-22 03:41:43 +00:00
|
|
|
private void linkMazeLevels5 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-22 03:41:43 +00:00
|
|
|
{
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
DefaultMutableTreeNode mazeNode = linkNode ("Maze", "Level 5 mazes", scenarioNode);
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> allMazeBlocks = new ArrayList<> ();
|
2016-08-22 03:41:43 +00:00
|
|
|
|
2016-09-01 04:01:47 +00:00
|
|
|
int dataSize = 0x39A;
|
2016-08-23 05:20:04 +00:00
|
|
|
int base = 0x1800;
|
2016-08-22 03:41:43 +00:00
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
{
|
2016-08-23 14:14:04 +00:00
|
|
|
int offset = base + i * 0x400;
|
2016-08-24 10:17:27 +00:00
|
|
|
byte[] data = new byte[0x800];
|
2016-09-01 04:01:47 +00:00
|
|
|
System.arraycopy (buffer, offset, data, 0, dataSize);
|
|
|
|
System.arraycopy (buffer, offset + 0x2000, data, 0x400, dataSize);
|
2016-08-23 14:14:04 +00:00
|
|
|
MazeGridV5 grid = new MazeGridV5 ("Maze level " + (i + 1), data, messageBlock);
|
2016-08-22 03:41:43 +00:00
|
|
|
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> mazeBlocks = new ArrayList<> ();
|
2016-09-01 04:01:47 +00:00
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
|
mazeBlocks.add (blocks.get (12 + i * 4 + j));
|
|
|
|
allMazeBlocks.addAll (mazeBlocks);
|
|
|
|
|
2016-08-22 03:41:43 +00:00
|
|
|
addToNode (grid, mazeNode, mazeBlocks);
|
2016-08-16 06:34:23 +00:00
|
|
|
}
|
2016-09-01 04:01:47 +00:00
|
|
|
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) mazeNode.getUserObject ();
|
|
|
|
afs.setSectors (allMazeBlocks);
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
private void linkBlock1 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
{
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
StringBuilder text = new StringBuilder ();
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> allBlocks = new ArrayList<> ();
|
2016-09-01 04:01:47 +00:00
|
|
|
for (int i = 0; i < 23; i++)
|
|
|
|
{
|
|
|
|
allBlocks.add (blocks.get (44 + i));
|
|
|
|
}
|
|
|
|
|
|
|
|
int offset = 0x5800;
|
|
|
|
int length = 66;
|
|
|
|
for (int i = 0; i < 179; i++)
|
|
|
|
{
|
|
|
|
text.append (String.format ("%04X : %s%n", (offset + i * length),
|
|
|
|
HexFormatter.getHexString (buffer, offset + i * length, length)));
|
|
|
|
}
|
|
|
|
|
2022-05-03 05:36:37 +00:00
|
|
|
DefaultMutableTreeNode oracleNode = linkNode ("Block1", text.toString (), scenarioNode);
|
2016-09-01 04:01:47 +00:00
|
|
|
oracleNode.setAllowsChildren (false);
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) oracleNode.getUserObject ();
|
|
|
|
afs.setSectors (allBlocks);
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
private void linkBlock2 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
{
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
StringBuilder text = new StringBuilder ();
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> allBlocks = new ArrayList<> ();
|
2016-09-01 04:01:47 +00:00
|
|
|
for (int i = 0; i < 19; i++)
|
|
|
|
{
|
|
|
|
allBlocks.add (blocks.get (87 + i));
|
|
|
|
}
|
|
|
|
|
|
|
|
int offset = 0xAE00;
|
|
|
|
int length = 60;
|
|
|
|
for (int i = 0; i < 150; i++)
|
|
|
|
{
|
|
|
|
text.append (String.format ("%04X : %s%n", (offset + i * length),
|
|
|
|
HexFormatter.getHexString (buffer, offset + i * length, length)));
|
|
|
|
}
|
|
|
|
|
2022-05-03 05:36:37 +00:00
|
|
|
DefaultMutableTreeNode oracleNode = linkNode ("Block2", text.toString (), scenarioNode);
|
2016-09-01 04:01:47 +00:00
|
|
|
oracleNode.setAllowsChildren (false);
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) oracleNode.getUserObject ();
|
|
|
|
afs.setSectors (allBlocks);
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
private void linkOracle (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-09-01 04:01:47 +00:00
|
|
|
{
|
|
|
|
byte[] buffer = fileEntry.getDataSource ().buffer;
|
|
|
|
List<DiskAddress> blocks = fileEntry.getSectors ();
|
|
|
|
|
|
|
|
StringBuilder text = new StringBuilder ();
|
|
|
|
|
|
|
|
for (int i = 0; i < 320; i++)
|
|
|
|
{
|
|
|
|
// System.out.println (HexFormatter.format (buffer, 0x08600 + i * 32, 32));
|
|
|
|
int offset = 0x08600 + i * 32 + 18;
|
2021-05-19 08:13:17 +00:00
|
|
|
int key = Utility.getShort (buffer, offset);
|
2016-09-01 04:01:47 +00:00
|
|
|
if (key > 0)
|
2022-05-03 05:36:37 +00:00
|
|
|
text.append (
|
2022-05-28 02:59:25 +00:00
|
|
|
String.format ("%04X %04X * %s%n", offset, key, messageBlock.getMessageLine (key)));
|
2021-05-19 08:13:17 +00:00
|
|
|
key = Utility.getShort (buffer, offset + 8);
|
2016-09-01 04:01:47 +00:00
|
|
|
if (key > 0)
|
|
|
|
text.append (String.format ("%04X %04X %s%n", offset + 8, key,
|
2022-05-28 02:59:25 +00:00
|
|
|
messageBlock.getMessageLine (key)));
|
2016-09-01 04:01:47 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> allOracleBlocks = new ArrayList<> ();
|
2016-09-01 04:01:47 +00:00
|
|
|
for (int i = 0; i < 20; i++)
|
|
|
|
{
|
|
|
|
allOracleBlocks.add (blocks.get (67 + i));
|
|
|
|
}
|
|
|
|
|
2022-05-03 05:36:37 +00:00
|
|
|
DefaultMutableTreeNode oracleNode = linkNode ("Oracle", text.toString (), scenarioNode);
|
2016-09-01 04:01:47 +00:00
|
|
|
oracleNode.setAllowsChildren (false);
|
|
|
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) oracleNode.getUserObject ();
|
|
|
|
afs.setSectors (allOracleBlocks);
|
2016-08-16 06:34:23 +00:00
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2022-05-03 05:36:37 +00:00
|
|
|
private void addToNode (AbstractFile af, DefaultMutableTreeNode node, List<DiskAddress> blocks)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-14 08:41:19 +00:00
|
|
|
{
|
2022-05-03 05:36:37 +00:00
|
|
|
DefaultAppleFileSource dafs = new DefaultAppleFileSource (af.getName (), af, this, blocks);
|
2016-08-14 08:41:19 +00:00
|
|
|
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (dafs);
|
|
|
|
childNode.setAllowsChildren (false);
|
2016-08-19 09:57:29 +00:00
|
|
|
node.add (childNode);
|
2016-08-08 04:53:29 +00:00
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2022-05-03 05:36:37 +00:00
|
|
|
private DefaultMutableTreeNode linkNode (String name, String text, DefaultMutableTreeNode parent)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-16 06:34:23 +00:00
|
|
|
{
|
|
|
|
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
|
|
|
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
|
|
|
|
parent.add (node);
|
2022-05-27 08:30:30 +00:00
|
|
|
|
2016-08-16 06:34:23 +00:00
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-14 08:41:19 +00:00
|
|
|
public static boolean isWizardryIVorV (Disk disk, boolean debug)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-08 04:53:29 +00:00
|
|
|
{
|
2016-08-14 08:41:19 +00:00
|
|
|
// Wizardry IV or V boot code
|
2016-08-08 04:53:29 +00:00
|
|
|
byte[] header = { 0x00, (byte) 0xEA, (byte) 0xA9, 0x60, (byte) 0x8D, 0x01, 0x08 };
|
2020-04-10 23:47:52 +00:00
|
|
|
byte[] buffer = disk.readBlock (0);
|
2016-08-08 04:53:29 +00:00
|
|
|
|
|
|
|
if (!Utility.matches (buffer, 0, header))
|
|
|
|
return false;
|
|
|
|
|
2020-04-10 23:47:52 +00:00
|
|
|
buffer = disk.readBlock (1);
|
2022-05-03 05:36:37 +00:00
|
|
|
return buffer[510] == 1 && buffer[511] == 0; // disk #1
|
2016-08-08 04:53:29 +00:00
|
|
|
}
|
|
|
|
}
|