mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-06-03 16:29:29 +00:00
Added characters to Wiz4
This commit is contained in:
parent
1b86b31233
commit
0b72f1a37d
|
@ -165,7 +165,7 @@ public class AppleDisk implements Disk
|
||||||
this.sectorSize = 512;
|
this.sectorSize = 512;
|
||||||
this.trackSize = sectors * sectorSize;
|
this.trackSize = sectors * sectorSize;
|
||||||
}
|
}
|
||||||
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4
|
else if (file.length () == 143360 && tracks == 256 && sectors == 8) // wiz4 or wiz5
|
||||||
{
|
{
|
||||||
this.blocks = tracks * sectors;
|
this.blocks = tracks * sectors;
|
||||||
this.sectorSize = 512;
|
this.sectorSize = 512;
|
||||||
|
|
|
@ -861,9 +861,12 @@ public class DiskFactory
|
||||||
System.out.println ("checking Wizardry IV or V");
|
System.out.println ("checking Wizardry IV or V");
|
||||||
|
|
||||||
String fileName = file.getAbsolutePath ().toLowerCase ();
|
String fileName = file.getAbsolutePath ().toLowerCase ();
|
||||||
int pos = file.getAbsolutePath ().indexOf ('.');
|
int pos = fileName.lastIndexOf ('.');
|
||||||
char c = fileName.charAt (pos - 1);
|
char c = fileName.charAt (pos - 1); // '1' (wiz4) or 'a' (wiz5)
|
||||||
int requiredDisks = c == '1' ? 6 : c == 'a' ? 10 : 0;
|
int requiredDisks = c == '1' ? 7 : c == 'a' ? 10 : 0;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.out.printf ("Required disks: %d%n", requiredDisks);
|
||||||
|
|
||||||
if (requiredDisks > 0)
|
if (requiredDisks > 0)
|
||||||
{
|
{
|
||||||
|
@ -884,7 +887,7 @@ public class DiskFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Not a Wizardry IV disk");
|
System.out.println ("Not a Wizardry IV or V disk");
|
||||||
|
|
||||||
PascalDisk pascalDisk = new PascalDisk (disk);
|
PascalDisk pascalDisk = new PascalDisk (disk);
|
||||||
return pascalDisk;
|
return pascalDisk;
|
||||||
|
@ -894,6 +897,9 @@ public class DiskFactory
|
||||||
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
|
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println ("Collecting Wizardry disks");
|
||||||
|
|
||||||
char c = fileName.charAt (dotPos - 1);
|
char c = fileName.charAt (dotPos - 1);
|
||||||
String suffix = fileName.substring (dotPos + 1);
|
String suffix = fileName.substring (dotPos + 1);
|
||||||
|
|
||||||
|
@ -901,8 +907,11 @@ public class DiskFactory
|
||||||
{
|
{
|
||||||
String old = new String (c + "." + suffix);
|
String old = new String (c + "." + suffix);
|
||||||
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
||||||
|
|
||||||
File f = new File (fileName.replace (old, rep));
|
File f = new File (fileName.replace (old, rep));
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
System.out.println (f);
|
||||||
|
|
||||||
if (!f.exists () || !f.isFile ())
|
if (!f.exists () || !f.isFile ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ class Character extends AbstractFile
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
super (name, buffer);
|
super (name, buffer);
|
||||||
|
|
||||||
this.scenario = scenario;
|
this.scenario = scenario;
|
||||||
|
|
||||||
attributes = new Attributes ();
|
attributes = new Attributes ();
|
||||||
|
|
16
src/com/bytezone/diskbrowser/wizardry/Character4.java
Normal file
16
src/com/bytezone/diskbrowser/wizardry/Character4.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package com.bytezone.diskbrowser.wizardry;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class Character4 extends AbstractFile
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
Character4 (String name, byte[] buffer)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
super (name, buffer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,13 @@ class Header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
ScenarioData get (int index)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
return data.get (index);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void linkText (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
|
private void linkText (String title, DiskAddress da, DefaultMutableTreeNode headerNode)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.bytezone.diskbrowser.wizardry;
|
package com.bytezone.diskbrowser.wizardry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
||||||
|
|
||||||
// Based on a pascal routine by Tom Ewers
|
// Based on a pascal routine by Tom Ewers
|
||||||
|
@ -28,19 +31,52 @@ class Huffman extends AbstractFile
|
||||||
super (name, buffer);
|
super (name, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
byte[] decodeMessage (byte[] buffer, int offset, int length)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
this.message = buffer;
|
||||||
|
List<Byte> decoded = new ArrayList<> ();
|
||||||
|
int retPtr = 0;
|
||||||
|
int max = offset + length;
|
||||||
|
|
||||||
|
depth = 0;
|
||||||
|
msgPtr = offset;
|
||||||
|
currentByte = 0;
|
||||||
|
|
||||||
|
while (msgPtr < max)
|
||||||
|
decoded.add (getChar ());
|
||||||
|
|
||||||
|
byte[] returnBuffer = new byte[decoded.size ()];
|
||||||
|
for (byte b : decoded)
|
||||||
|
returnBuffer[retPtr++] = b;
|
||||||
|
|
||||||
|
return returnBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
String decodeMessage (byte[] message)
|
String decodeMessage (byte[] message)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
|
||||||
depth = 0;
|
depth = 0;
|
||||||
msgPtr = 0;
|
msgPtr = 0;
|
||||||
currentByte = 0;
|
currentByte = 0;
|
||||||
|
|
||||||
int len = getChar ();
|
int len = getChar () & 0xFF;
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
text.append ((char) getChar ());
|
{
|
||||||
|
int c = getChar () & 0xFF;
|
||||||
|
text.append (switch (c)
|
||||||
|
{
|
||||||
|
case 0x09 -> " OF ";
|
||||||
|
case 0x0A -> "POTION";
|
||||||
|
case 0x0B -> "STAFF";
|
||||||
|
default -> c < 32 ? '?' : (char) c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,21 +40,21 @@ public class Relocator extends AbstractFile
|
||||||
for (DiskSegment diskSegment : diskRecord.diskSegments)
|
for (DiskSegment diskSegment : diskRecord.diskSegments)
|
||||||
{
|
{
|
||||||
int lo = diskSegment.logicalBlock;
|
int lo = diskSegment.logicalBlock;
|
||||||
int hi = diskSegment.logicalBlock + diskSegment.segmentLength;
|
int hi = lo + diskSegment.segmentLength;
|
||||||
|
|
||||||
for (int i = lo, count = 0; i < hi; i++, count++)
|
for (int i = lo, count = 0; i < hi; i++, count++)
|
||||||
// if (diskBlocks[i] == 0) // doesn't matter either way
|
if (diskBlocks[i] == 0) // doesn't matter either way
|
||||||
{
|
|
||||||
if (diskBlocks[i] != 0 && false)
|
|
||||||
{
|
{
|
||||||
System.out.print ("was: ");
|
if (diskBlocks[i] != 0 && false)
|
||||||
System.out.printf ("diskBlocks[%d] = %d%n", i, diskBlocks[i]);
|
{
|
||||||
System.out.print ("now: ");
|
System.out.print ("was: ");
|
||||||
System.out.printf ("diskBlocks[%d] = %d%n", i, diskRecord.diskNumber);
|
System.out.printf ("diskBlocks[%d] = %d%n", i, diskBlocks[i]);
|
||||||
|
System.out.print ("now: ");
|
||||||
|
System.out.printf ("diskBlocks[%d] = %d%n", i, diskRecord.diskNumber);
|
||||||
|
}
|
||||||
|
diskBlocks[i] = diskRecord.diskNumber;
|
||||||
|
diskOffsets[i] = diskSegment.physicalBlock + count;
|
||||||
}
|
}
|
||||||
diskBlocks[i] = diskRecord.diskNumber;
|
|
||||||
diskOffsets[i] = diskSegment.physicalBlock + count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ public class Relocator extends AbstractFile
|
||||||
public void createNewBuffer (Disk[] dataDisks)
|
public void createNewBuffer (Disk[] dataDisks)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
System.out.println (getText ());
|
||||||
|
|
||||||
AppleDisk master = (AppleDisk) dataDisks[0];
|
AppleDisk master = (AppleDisk) dataDisks[0];
|
||||||
// byte[] key1 = { 0x55, 0x55, 0x15, 0x55 };
|
// byte[] key1 = { 0x55, 0x55, 0x15, 0x55 };
|
||||||
// byte[] key2 = { 0x00, 0x00, 0x01, 0x41 };
|
// byte[] key2 = { 0x00, 0x00, 0x01, 0x41 };
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
{
|
{
|
||||||
super (dataDisks[0]);
|
super (dataDisks[0]);
|
||||||
|
|
||||||
version = dataDisks.length == 6 ? 4 : dataDisks.length == 10 ? 5 : 0;
|
version = dataDisks.length == 7 ? 4 : dataDisks.length == 10 ? 5 : 0;
|
||||||
|
|
||||||
DefaultTreeModel model = (DefaultTreeModel) catalogTree.getModel ();
|
DefaultTreeModel model = (DefaultTreeModel) catalogTree.getModel ();
|
||||||
DefaultMutableTreeNode currentRoot = (DefaultMutableTreeNode) model.getRoot ();
|
DefaultMutableTreeNode currentRoot = (DefaultMutableTreeNode) model.getRoot ();
|
||||||
|
@ -83,6 +83,7 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scenario data
|
||||||
if (version == 4)
|
if (version == 4)
|
||||||
{
|
{
|
||||||
DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA");
|
DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA");
|
||||||
|
@ -92,6 +93,7 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
fileEntry.setFile (null);
|
fileEntry.setFile (null);
|
||||||
scenarioNode.setAllowsChildren (true);
|
scenarioNode.setAllowsChildren (true);
|
||||||
scenarioHeader = new Header (scenarioNode, this);
|
scenarioHeader = new Header (scenarioNode, this);
|
||||||
|
linkCharacters4 (scenarioNode, fileEntry);
|
||||||
linkMazeLevels4 (scenarioNode, fileEntry);
|
linkMazeLevels4 (scenarioNode, fileEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,10 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
linkBlock2 (scenarioNode, fileEntry);
|
linkBlock2 (scenarioNode, fileEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
System.out.println ("No Wizardry version set");
|
||||||
|
|
||||||
|
// monster images
|
||||||
if (version == 4)
|
if (version == 4)
|
||||||
{
|
{
|
||||||
DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS");
|
DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS");
|
||||||
|
@ -132,6 +137,72 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
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);
|
||||||
|
|
||||||
|
Character4 c = new Character4 (name, out);
|
||||||
|
List<DiskAddress> characterBlocks = new ArrayList<> ();
|
||||||
|
DiskAddress da = blocks.get (ptr / 512);
|
||||||
|
characterBlocks.add (da);
|
||||||
|
addToNode (c, charactersNode, characterBlocks);
|
||||||
|
|
||||||
|
if (!allCharacterBlocks.contains (da))
|
||||||
|
allCharacterBlocks.add (da);
|
||||||
|
|
||||||
|
ptr += sd.totalBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultAppleFileSource afs = (DefaultAppleFileSource) charactersNode.getUserObject ();
|
||||||
|
afs.setSectors (allCharacterBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void linkMonsterImages4 (DefaultMutableTreeNode monstersNode, FileEntry fileEntry)
|
private void linkMonsterImages4 (DefaultMutableTreeNode monstersNode, FileEntry fileEntry)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -168,30 +239,6 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
private void linkMazeLevels4 (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[0x380]; // 896
|
|
||||||
int offset = mazeData.dataOffset * 512 + i * 1024;
|
|
||||||
System.arraycopy (buffer, offset, level, 0, level.length);
|
|
||||||
|
|
||||||
List<DiskAddress> mazeBlocks = new ArrayList<> ();
|
|
||||||
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 linkMazeLevels5 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
private void linkMazeLevels5 (DefaultMutableTreeNode scenarioNode, FileEntry fileEntry)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@ -332,6 +379,7 @@ public class Wizardry4BootDisk extends PascalDisk
|
||||||
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
|
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
|
||||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
|
||||||
parent.add (node);
|
parent.add (node);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ public class WizardryScenarioDisk extends PascalDisk
|
||||||
{
|
{
|
||||||
byte[] buffer = disk.readBlock (2);
|
byte[] buffer = disk.readBlock (2);
|
||||||
int totalFiles = Utility.getShort (buffer, 16);
|
int totalFiles = Utility.getShort (buffer, 16);
|
||||||
|
|
||||||
if (totalFiles != 3)
|
if (totalFiles != 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user