From b5cf619733444bc69d2cf60f842498c1a8666ad7 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Mon, 22 Aug 2016 13:41:43 +1000 Subject: [PATCH] wiz 1-3 level formatting --- .../diskbrowser/utilities/HexFormatter.java | 3 +- .../diskbrowser/wizardry/DragonData.java | 17 ++ .../diskbrowser/wizardry/MazeCell.java | 9 +- .../diskbrowser/wizardry/MazeGridV5.java | 78 +++++ .../diskbrowser/wizardry/MazeLevel.java | 281 +++++++++++++++--- .../diskbrowser/wizardry/MessageBlock.java | 25 +- .../diskbrowser/wizardry/Wiz4Image.java | 28 +- .../diskbrowser/wizardry/Wiz5Monsters.java | 46 +++ .../wizardry/Wizardry4BootDisk.java | 82 +++-- 9 files changed, 475 insertions(+), 94 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/wizardry/DragonData.java create mode 100644 src/com/bytezone/diskbrowser/wizardry/MazeGridV5.java create mode 100644 src/com/bytezone/diskbrowser/wizardry/Wiz5Monsters.java diff --git a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java index f29c082..d1f9f58 100755 --- a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java +++ b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java @@ -41,6 +41,7 @@ public class HexFormatter { StringBuffer line = new StringBuffer (); int[] freq = new int[256]; + boolean startedOnBoundary = offset % 0x100 == 0; if (header) { @@ -55,7 +56,7 @@ public class HexFormatter { if (line.length () > 0 && i > 0) line.append ("\n"); - if (i > offset && (i % 0x200) == 0) + if (i > offset && startedOnBoundary && (i % 0x200) == 0) line.append ("\n"); // print offset diff --git a/src/com/bytezone/diskbrowser/wizardry/DragonData.java b/src/com/bytezone/diskbrowser/wizardry/DragonData.java new file mode 100644 index 0000000..44761e5 --- /dev/null +++ b/src/com/bytezone/diskbrowser/wizardry/DragonData.java @@ -0,0 +1,17 @@ +package com.bytezone.diskbrowser.wizardry; + +import com.bytezone.diskbrowser.applefile.AbstractFile; + +public class DragonData extends AbstractFile +{ + public DragonData (String name, byte[] buffer) + { + super (name, buffer); + } + + @Override + public String getText () + { + return "DragonData"; + } +} diff --git a/src/com/bytezone/diskbrowser/wizardry/MazeCell.java b/src/com/bytezone/diskbrowser/wizardry/MazeCell.java index 308b7df..37c0ed7 100755 --- a/src/com/bytezone/diskbrowser/wizardry/MazeCell.java +++ b/src/com/bytezone/diskbrowser/wizardry/MazeCell.java @@ -9,7 +9,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter; class MazeCell { - static Dimension cellSize = new Dimension (22, 22); // size in pixels + static Dimension cellSize = new Dimension (22, 22); // size in pixels boolean northWall; boolean southWall; @@ -43,7 +43,8 @@ class MazeCell int unknown; MazeAddress address; - MazeAddress addressTo; // if teleport/stairs/chute + MazeAddress addressTo; // if teleport/stairs/chute + public Message message; public List monsters; public Item itemRequired; @@ -131,7 +132,7 @@ class MazeCell private void drawEast (Graphics2D g, int x, int y) { g.drawLine (x + cellSize.width - 1, y + 1, x + cellSize.width - 1, - y + cellSize.height - 1); + y + cellSize.height - 1); } private void drawNorth (Graphics2D g, int x, int y) @@ -142,7 +143,7 @@ class MazeCell private void drawSouth (Graphics2D g, int x, int y) { g.drawLine (x + 1, y + cellSize.height - 1, x + cellSize.width - 1, - y + cellSize.height - 1); + y + cellSize.height - 1); } public void drawStairsUp (Graphics2D g, int x, int y) diff --git a/src/com/bytezone/diskbrowser/wizardry/MazeGridV5.java b/src/com/bytezone/diskbrowser/wizardry/MazeGridV5.java new file mode 100644 index 0000000..65bded5 --- /dev/null +++ b/src/com/bytezone/diskbrowser/wizardry/MazeGridV5.java @@ -0,0 +1,78 @@ +package com.bytezone.diskbrowser.wizardry; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +import com.bytezone.diskbrowser.applefile.AbstractFile; +import com.bytezone.diskbrowser.utilities.HexFormatter; + +public class MazeGridV5 extends AbstractFile +{ + MazeCell[][] grid = new MazeCell[8][8]; + + public MazeGridV5 (String name, byte[] buffer) + { + super (name, buffer); + + for (int row = 0; row < 8; row++) + for (int col = 0; col < 8; col++) + grid[row][col] = getLayout (row, col); + } + + @Override + public BufferedImage getImage () + { + Dimension cellSize = new Dimension (22, 22); + image = new BufferedImage (8 * cellSize.width + 1, 8 * cellSize.height + 1, + BufferedImage.TYPE_USHORT_555_RGB); + Graphics2D g = image.createGraphics (); + g.setRenderingHint (RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + for (int row = 0; row < 8; row++) + for (int column = 0; column < 8; column++) + { + MazeCell cell = grid[row][column]; + int x = column * cellSize.width; + int y = image.getHeight () - (row + 1) * cellSize.height - 1; + cell.draw (g, x, y); + } + return image; + } + + private MazeCell getLayout (int row, int column) + { + MazeAddress address = new MazeAddress (0, row, column); + MazeCell cell = new MazeCell (address); + + int offset = column * 2 + row / 4; + + int value = HexFormatter.intValue (buffer[offset]); + value >>>= (row % 4) * 2; + cell.westWall = ((value & 1) == 1); + value >>>= 1; + cell.westDoor = ((value & 1) == 1); + + value = HexFormatter.intValue (buffer[offset + 16]); + value >>>= (row % 4) * 2; + cell.southWall = ((value & 1) == 1); + value >>>= 1; + cell.southDoor = ((value & 1) == 1); + + value = HexFormatter.intValue (buffer[offset + 32]); + value >>>= (row % 4) * 2; + cell.eastWall = ((value & 1) == 1); + value >>>= 1; + cell.eastDoor = ((value & 1) == 1); + + value = HexFormatter.intValue (buffer[offset + 48]); + value >>>= (row % 4) * 2; + cell.northWall = ((value & 1) == 1); + value >>>= 1; + cell.northDoor = ((value & 1) == 1); + + return cell; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/MazeLevel.java b/src/com/bytezone/diskbrowser/wizardry/MazeLevel.java index 9913a62..9c60638 100755 --- a/src/com/bytezone/diskbrowser/wizardry/MazeLevel.java +++ b/src/com/bytezone/diskbrowser/wizardry/MazeLevel.java @@ -4,6 +4,7 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; +import java.util.ArrayList; import java.util.List; import com.bytezone.diskbrowser.applefile.AbstractFile; @@ -22,6 +23,125 @@ class MazeLevel extends AbstractFile this.level = level; } + @Override + public String getHexDump () + { + // StringBuilder text = new StringBuilder (super.getHexDump ()); + StringBuilder text = new StringBuilder (); + + text.append ("West walls/doors\n\n"); + text.append (HexFormatter.format (buffer, 0, 120)); + addWalls (text, 0); + + text.append ("\nSouth walls/doors\n\n"); + text.append (HexFormatter.format (buffer, 120, 120)); + addWalls (text, 120); + + text.append ("\nEast walls/doors\n\n"); + text.append (HexFormatter.format (buffer, 240, 120)); + addWalls (text, 240); + + text.append ("\nNorth walls/doors\n\n"); + text.append (HexFormatter.format (buffer, 360, 120)); + addWalls (text, 360); + + text.append ("\nEncounters\n\n"); + text.append (HexFormatter.format (buffer, 480, 80)); + addEncounters (text, 480); + + text.append ("\nExtras\n\n"); + text.append (HexFormatter.format (buffer, 560, 200)); + addExtras (text, 560); + + text.append ("\nIndex\n\n"); + text.append ( + String.format ("%04X: %s%n%n", 760, HexFormatter.getHexString (buffer, 760, 8))); + + text.append (" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); + text.append (String.format ("%04X: ", 760)); + for (int i = 0; i < 8; i++) + { + int val = buffer[760 + i] & 0xFF; + text.append (String.format ("%X:%X ", val % 16, val / 16)); + } + + String[] extras = + { "", "Stairs", "Pit", "Chute", "Spinner", "Darkness", "Teleport", "Ouch", + "Elevator", "Rock/Water", "Fizzle", "Message/Item", "Monster" }; + + List messageList = new ArrayList (); + text.append ("\n\nAddresses/Messages/Items\n\n"); + for (int i = 768, j = 0; i < 800; i += 2, j++) + { + int val = buffer[760 + j / 2] & 0xFF; + String extra = (j % 2) == 0 ? extras[val % 16] : extras[val / 16]; + MazeAddress address = getAddress (j); + int k = (j % 2) == 0 ? val % 16 : val / 16; + if (k == 11) + messageList.add (address); + text.append (String.format ("%04X-%04X-%04X: %04X %04X %04X : %X %X %s%n", i, + i + 32, i + 64, address.level, address.row, address.column, j, k, extra)); + } + + text.append ("\nRest\n\n"); + text.append (HexFormatter.format (buffer, 864, buffer.length - 864)); + + text.append ("\n\n"); + for (MazeAddress address : messageList) + { + Message message = getMessage (address.row); + text.append (address.row + "\n"); + text.append (message.getText ()); + text.append ("\n"); + } + + return text.toString (); + } + + private void addWalls (StringBuilder text, int ptr) + { + text.append ("\n\n"); + for (int i = 0; i < 20; i++) + text.append (String.format (" Col %2d: %s%n", i, + HexFormatter.getHexString (buffer, ptr + i * 6, 6))); + } + + private void addEncounters (StringBuilder text, int ptr) + { + text.append ("\n\n"); + for (int i = 0; i < 20; i++) + text.append (String.format (" Col %2d: %s%n", i, + HexFormatter.getHexString (buffer, ptr + i * 4, 4))); + } + + private void addExtras (StringBuilder text, int ptr) + { + // StringBuilder text2 = new StringBuilder (); + text.append ("\n\n"); + for (int i = 0; i < 20; i++) + { + text.append (String.format (" Col %2d: ", i)); + for (int j = 0; j < 10; j++) + { + int val = buffer[ptr + i * 10 + j] & 0xFF; + int left = val / 16; // 0:F + int right = val % 16; // 0:F + text.append (String.format ("%X:%X ", right, left)); + + int c2 = buffer[760 + right / 2] & 0xFF; // 760 + 0:7 + int d2 = (right % 2 == 0) ? c2 % 16 : c2 / 16; + // text2.append (String.format ("%02X %02X ", c2, d2)); + + int c1 = buffer[760 + left / 2] & 0xFF; + int d1 = (left % 2 == 0) ? c1 % 16 : c1 / 16; + // text2.append (String.format ("%02X %02X%n", c1, d1)); + } + text.append ("\n"); + // text2.append ("\n"); + } + // text.append (text2.toString ()); + } + @Override public BufferedImage getImage () { @@ -64,50 +184,60 @@ class MazeLevel extends AbstractFile MazeCell cell = new MazeCell (address); // doors and walls + int BYTES_PER_COL = 6; // 20 / 4 = 5 bytes + 1 wasted + int CELLS_PER_BYTE = 4; // 2 bits each + int BITS_PER_ROW = 2; - int offset = column * 6 + row / 4; // 6 bytes/column + int offset = column * BYTES_PER_COL + row / CELLS_PER_BYTE; - int value = HexFormatter.intValue (buffer[offset]); - value >>>= (row % 4) * 2; - cell.westWall = ((value & 1) == 1); - value >>>= 1; - cell.westDoor = ((value & 1) == 1); + int value = buffer[offset] & 0xFF; + value >>>= (row % CELLS_PER_BYTE) * BITS_PER_ROW; // push 0, 2, 4, 6 bits + cell.westWall = ((value & 1) == 1); // use rightmost bit + value >>>= 1; // push 1 bit + cell.westDoor = ((value & 1) == 1); // use rightmost bit - value = HexFormatter.intValue (buffer[offset + 120]); - value >>>= (row % 4) * 2; + value = buffer[offset + 120] & 0xFF; + value >>>= (row % CELLS_PER_BYTE) * BITS_PER_ROW; cell.southWall = ((value & 1) == 1); value >>>= 1; cell.southDoor = ((value & 1) == 1); - value = HexFormatter.intValue (buffer[offset + 240]); - value >>>= (row % 4) * 2; + value = buffer[offset + 240] & 0xFF; + value >>>= (row % CELLS_PER_BYTE) * BITS_PER_ROW; cell.eastWall = ((value & 1) == 1); value >>>= 1; cell.eastDoor = ((value & 1) == 1); - value = HexFormatter.intValue (buffer[offset + 360]); - value >>>= (row % 4) * 2; + value = buffer[offset + 360] & 0xFF; + value >>>= (row % CELLS_PER_BYTE) * BITS_PER_ROW; cell.northWall = ((value & 1) == 1); value >>>= 1; cell.northDoor = ((value & 1) == 1); // monster table + BYTES_PER_COL = 4; // 3 bytes + 1 wasted + CELLS_PER_BYTE = 8; // 1 bit each + BITS_PER_ROW = 1; - offset = column * 4 + row / 8; // 4 bytes/column, 1 bit/row - value = HexFormatter.intValue (buffer[offset + 480]); + offset = column * BYTES_PER_COL + row / CELLS_PER_BYTE; // 4 bytes/column, 1 bit/row + value = buffer[offset + 480] & 0xFF; value >>>= row % 8; cell.monsterLair = ((value & 1) == 1); - // stairs, pits, darkness etc. + // square extra offset = column * 10 + row / 2; // 10 bytes/column, 4 bits/row - value = HexFormatter.intValue (buffer[offset + 560]); - int b = (row % 2 == 0) ? value % 16 : value / 16; - int c = HexFormatter.intValue (buffer[760 + b / 2]); + value = buffer[offset + 560] & 0xFF; + int b = (row % 2 == 0) ? value % 16 : value / 16; // 0:F + + int c = buffer[760 + b / 2] & 0xFF; // 760:767 int d = (b % 2 == 0) ? c % 16 : c / 16; switch (d) { + case 0: // normal + break; + case 1: cell.stairs = true; cell.addressTo = getAddress (b); @@ -135,15 +265,20 @@ class MazeLevel extends AbstractFile cell.addressTo = getAddress (b); break; - case 8: - cell.elevator = true; - cell.elevatorTo = - HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]); - cell.elevatorFrom = - HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); + case 7: // ouchy + cell.unknown = d; break; - case 9: + case 8: + cell.elevator = true; + MazeAddress elevatorAddress = getAddress (b); + cell.elevatorTo = elevatorAddress.row; + // HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]); + cell.elevatorFrom = elevatorAddress.column; + // HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); + break; + + case 9: // rock/water cell.rock = true; break; @@ -152,38 +287,36 @@ class MazeLevel extends AbstractFile break; case 11: - int messageNum = HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]); - if (messages != null) - { - for (Message m : messages) - if (m.match (messageNum)) - { - cell.message = m; - break; - } - if (cell.message == null) - System.out.println ("message not found : " + messageNum); - } - cell.messageType = - HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); + MazeAddress messageAddress = getAddress (b); + // int messageNum = HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]); + + Message m = getMessage (messageAddress.row); + if (m != null) + cell.message = m; + + cell.messageType = messageAddress.column; + // HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); int itemID = -1; if (cell.messageType == 2 && items != null) // obtain Item { - itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + // itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + itemID = messageAddress.level; cell.itemObtained = items.get (itemID); } - if (cell.messageType == 5 && items != null) // requires Item + if (cell.messageType == 5 && items != null) // requires Item { - itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + // itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + itemID = messageAddress.level; cell.itemRequired = items.get (itemID); } if (cell.messageType == 4) { - value = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + // value = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]); + itemID = messageAddress.level; if (value <= 100) { cell.monsterID = value; @@ -203,11 +336,14 @@ class MazeLevel extends AbstractFile break; case 12: - cell.monsterID = HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); + MazeAddress monsterAddress = getAddress (b); + // cell.monsterID = HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]); + cell.monsterID = monsterAddress.column; cell.monsters = monsters; break; default: + System.out.println ("Unknown extra: " + d); cell.unknown = d; break; } @@ -215,12 +351,26 @@ class MazeLevel extends AbstractFile return cell; } - private MazeAddress getAddress (int a) + private MazeAddress getAddress (int b) // 0:F { - int b = a * 2; - return new MazeAddress (HexFormatter.intValue (buffer[768 + b], buffer[769 + b]), - HexFormatter.intValue (buffer[800 + b], buffer[801 + b]), - HexFormatter.intValue (buffer[832 + b], buffer[833 + b])); + int x = b * 2; + return new MazeAddress (HexFormatter.intValue (buffer[768 + x], buffer[769 + x]), + HexFormatter.intValue (buffer[800 + x], buffer[801 + x]), + HexFormatter.intValue (buffer[832 + x], buffer[833 + x])); + } + + private Message getMessage (int messageNo) + { + if (messages == null) + return null; + + for (Message m : messages) + if (m.match (messageNo)) + return m; + + // if (cell.message == null) + // System.out.println ("message not found : " + messageNum); + return null; } public int getRows () @@ -232,4 +382,37 @@ class MazeLevel extends AbstractFile { return 20; } + /* + * Pascal code decompiled by Tom Ewers + * + * TWALL = (OPEN, WALL, DOOR, HIDEDOOR); + + TSQUARE = (NORMAL, STAIRS, PIT, CHUTE, SPINNER, DARK, TRANSFER, + OUCHY, BUTTONZ, ROCKWATE, FIZZLE, SCNMSG, ENCOUNTE); + + TMAZE = RECORD + W : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF TWALL; + S : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF TWALL; + E : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF TWALL; + N : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF TWALL; + + FIGHTS : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF 0..1; + + SQREXTRA : PACKED ARRAY[ 0..19] OF PACKED ARRAY[ 0..19] OF 0..15; + + SQRETYPE : PACKED ARRAY[ 0..15] OF TSQUARE; + + AUX0 : PACKED ARRAY[ 0..15] OF INTEGER; + AUX1 : PACKED ARRAY[ 0..15] OF INTEGER; + AUX2 : PACKED ARRAY[ 0..15] OF INTEGER; + + ENMYCALC : PACKED ARRAY[ 1..3] OF RECORD + MINENEMY : INTEGER; + MULTWORS : INTEGER; + WORSE01 : INTEGER; + RANGE0N : INTEGER; + PERCWORS : INTEGER; + END; + END; + */ } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/MessageBlock.java b/src/com/bytezone/diskbrowser/wizardry/MessageBlock.java index b5f42c4..891749c 100644 --- a/src/com/bytezone/diskbrowser/wizardry/MessageBlock.java +++ b/src/com/bytezone/diskbrowser/wizardry/MessageBlock.java @@ -5,17 +5,21 @@ import java.util.Iterator; import java.util.List; import com.bytezone.common.Utility; +import com.bytezone.diskbrowser.applefile.AbstractFile; -public class MessageBlock implements Iterable +public class MessageBlock extends AbstractFile implements Iterable { private final int indexOffset; private final int indexLength; + private String text; private final List messageDataBlocks = new ArrayList (); public MessageBlock (byte[] buffer, Huffman huffman) { + super ("bollocks", buffer); + indexOffset = Utility.getWord (buffer, 0); indexLength = Utility.getWord (buffer, 2); @@ -43,6 +47,25 @@ public class MessageBlock implements Iterable return null; } + @Override + public String getText () + { + if (text != null) + return text; + + StringBuilder text = new StringBuilder (); + + for (MessageDataBlock mdb : messageDataBlocks) + { + text.append (mdb); + text.append ("\n"); + } + + this.text = text.toString (); + + return this.text; + } + @Override public Iterator iterator () { diff --git a/src/com/bytezone/diskbrowser/wizardry/Wiz4Image.java b/src/com/bytezone/diskbrowser/wizardry/Wiz4Image.java index 903ae57..0d27116 100644 --- a/src/com/bytezone/diskbrowser/wizardry/Wiz4Image.java +++ b/src/com/bytezone/diskbrowser/wizardry/Wiz4Image.java @@ -5,33 +5,27 @@ import java.awt.image.DataBuffer; public class Wiz4Image extends AbstractImage { - public Wiz4Image (String name, byte[] buffer) + public Wiz4Image (String name, byte[] buffer, int rows, int cols) // 5, 6 { super (name, buffer); - image = new BufferedImage (42, 40, BufferedImage.TYPE_BYTE_GRAY); // width/height + image = new BufferedImage (cols * 7, rows * 8, BufferedImage.TYPE_BYTE_GRAY); DataBuffer db = image.getRaster ().getDataBuffer (); int element = 0; - for (int row = 0; row < 5; row++) - { + int rowSize = cols * 8; + for (int row = 0; row < rows; row++) for (int line = 0; line < 8; line++) - { - for (int col = 0; col < 6; col++) + for (int col = 0; col < cols; col++) { - int ptr = row * 48 + col * 8 + line; + byte b = buffer[row * rowSize + col * 8 + line]; + for (int bit = 0; bit < 7; bit++) { - byte b = buffer[ptr]; - for (int bit = 0; bit < 7; bit++) - { - if ((b & 0x01) == 0x01) - db.setElem (element, 255); - b >>>= 1; - element++; - } + if ((b & 0x01) == 0x01) + db.setElem (element, 255); + b >>>= 1; + element++; } } - } - } } } diff --git a/src/com/bytezone/diskbrowser/wizardry/Wiz5Monsters.java b/src/com/bytezone/diskbrowser/wizardry/Wiz5Monsters.java new file mode 100644 index 0000000..73af41d --- /dev/null +++ b/src/com/bytezone/diskbrowser/wizardry/Wiz5Monsters.java @@ -0,0 +1,46 @@ +package com.bytezone.diskbrowser.wizardry; + +import java.util.ArrayList; +import java.util.List; + +import com.bytezone.common.Utility; +import com.bytezone.diskbrowser.applefile.AbstractFile; +import com.bytezone.diskbrowser.utilities.HexFormatter; + +public class Wiz5Monsters extends AbstractFile +{ + List images = new ArrayList (); + + public Wiz5Monsters (String name, byte[] buffer) + { + super (name, buffer); + + for (int i = 0; i < 10; i++) + { + int ptr = buffer[i] * 512; + byte[] data = new byte[512]; + System.arraycopy (buffer, ptr, data, 0, data.length); + Wiz4Image image = new Wiz4Image ("Image " + i, data, 10, 6); // no good + images.add (image); + } + } + + @Override + public String getText () + { + StringBuilder text = new StringBuilder (); + + int ptr = 0; + while (buffer[ptr] != 0) + { + int val1 = buffer[ptr] & 0xFF; + int val2 = Utility.getWord (buffer, ptr * 2 + 256); + text.append (String.format ("%3d %02X %04X :", ptr, val1, val2)); + String line = HexFormatter.getHexString (buffer, val1 * 512, 512); + text.append (line); + text.append ("\n"); + ptr++; + } + return text.toString (); + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java b/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java index 795b405..8dfc003 100644 --- a/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java +++ b/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java @@ -57,22 +57,25 @@ public class Wizardry4BootDisk extends PascalDisk if (version == 4) { DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "SCENARIO.DATA"); - - if (scenarioNode != null) + fileEntry = (FileEntry) scenarioNode.getUserObject (); + if (fileEntry != null) { - fileEntry = (FileEntry) scenarioNode.getUserObject (); - if (fileEntry != null) - { - fileEntry.setFile (null); - scenarioNode.setAllowsChildren (true); - scenarioHeader = new Header (scenarioNode, this); - linkMazeLevels4 (scenarioNode, fileEntry); - } + fileEntry.setFile (null); + scenarioNode.setAllowsChildren (true); + scenarioHeader = new Header (scenarioNode, this); + linkMazeLevels4 (scenarioNode, fileEntry); } } else if (version == 5) { DefaultMutableTreeNode scenarioNode = findNode (currentRoot, "DRAGON.DATA"); + fileEntry = (FileEntry) scenarioNode.getUserObject (); + if (fileEntry != null) + { + fileEntry.setFile (null); + scenarioNode.setAllowsChildren (true); + linkMazeLevels5 (scenarioNode, fileEntry); + } } if (version == 4) @@ -86,6 +89,24 @@ public class Wizardry4BootDisk extends PascalDisk linkMonsterImages4 (monstersNode, fileEntry); } } + else if (version == 5) + { + DefaultMutableTreeNode monstersNode = findNode (currentRoot, "200.MONSTERS"); + fileEntry = (FileEntry) monstersNode.getUserObject (); + if (fileEntry != null) + { + Wiz5Monsters w5monsters = + new Wiz5Monsters ("monsters", fileEntry.getDataSource ().buffer); + fileEntry.setFile (w5monsters); + monstersNode.setAllowsChildren (true); + for (Wiz4Image image : w5monsters.images) + { + List monsterBlocks = new ArrayList (); + // monsterBlocks.add (pictureBlocks.get (block)); + addToNode (image, monstersNode, monsterBlocks); + } + } + } DefaultMutableTreeNode huffNode = findNode (currentRoot, "ASCII.HUFF"); fileEntry = (FileEntry) huffNode.getUserObject (); @@ -103,6 +124,7 @@ public class Wizardry4BootDisk extends PascalDisk if (fileEntry != null) { messageBlock = new MessageBlock (fileEntry.getDataSource ().buffer, huffman); + fileEntry.setFile (messageBlock); messagesNode.setAllowsChildren (true); List blocks = fileEntry.getSectors (); @@ -126,18 +148,34 @@ public class Wizardry4BootDisk extends PascalDisk DefaultMutableTreeNode mazeNode = linkNode ("Maze", "Levels string", scenarioNode); for (int i = 0; i < 15; i++) { - byte[] level = new byte[896]; + byte[] level = new byte[0x380]; // 896 int offset = mazeData.dataOffset * 512 + i * 1024; - if (offset + level.length < buffer.length) - { - System.arraycopy (buffer, offset, level, 0, level.length); + System.arraycopy (buffer, offset, level, 0, level.length); - List 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); - } + List 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) + { + byte[] buffer = fileEntry.getDataSource ().buffer; + List blocks = fileEntry.getSectors (); + + DefaultMutableTreeNode mazeNode = linkNode ("Maze", "Level 5 mazes", scenarioNode); + + for (int i = 0; i < 8; i++) + { + int offset = 6144 + i * 256; + byte[] data = new byte[256]; + System.arraycopy (buffer, offset, data, 0, data.length); + MazeGridV5 grid = new MazeGridV5 ("test level " + i, data); + + List mazeBlocks = new ArrayList (); + addToNode (grid, mazeNode, mazeBlocks); } } @@ -154,8 +192,8 @@ public class Wizardry4BootDisk extends PascalDisk for (int pic = 0; pic < 2; pic++) { byte[] buffer = new byte[240]; - System.arraycopy (pictureBuffer, ptr + pic * 256, buffer, 0, 240); - Wiz4Image image = new Wiz4Image ("Image " + count++, buffer); + System.arraycopy (pictureBuffer, ptr + pic * 256, buffer, 0, buffer.length); + Wiz4Image image = new Wiz4Image ("Image " + count++, buffer, 5, 6); List monsterBlocks = new ArrayList (); monsterBlocks.add (pictureBlocks.get (block)); addToNode (image, monstersNode, monsterBlocks);